Wednesday, 15 July 2015

QTP ADVANCED PROGRAMMING



Advanced Programming In Quick Test Pro

This document describes the various commands that can be used for developing scripts using QTP and some tips to improve the performance of a QTP script.

Prerequisites: Basic knowledge of QTP.

Keywords: Quick Test Professional, Oracle application.

Introduction

The aim of this BOOK – Advanced QTP Programming is to educate the QTP programmers about the various possibilities of programming using the mercury product – Quick Test Professional. The content mentioned in this article is purely based on the experience gained from our project. The basic commands which are mentioned in the help files of QTP are not discussed in detail here. It is assumed that the readers have a fair idea of QTP tool and have developed at least one or two scripts.

Quick Test Professional (QTP) works on the principles of object identification. An object that exists in the front end of an application is identified by comparing the properties of that object with the properties stored in the object repository of QTP. If a perfect match is found that object is identified and all operations that can be performed by a user on that object can be simulated using the QTP commands. 

Section I

In this section, we will discuss about the various commands that can be used while running a QTP script. I assume that the version of QTP used is 8.0 or above. Some of the commands mentioned may not work for lower versions of QTP.

1)    To close all open browsers and objects

QTP works on the principles of unique object identification .If two or more browsers or application windows are open and the same object exist in both the browsers, QTP will get confused and unique object identification will fail .In order to avoid such failures, it is always preferred to close all open browsers and objects using the following commands.

    SystemUtil.CloseProcessByName ("iexplore.exe")
    SystemUtil.CloseProcessByName ("excel.exe")
    SystemUtil.CloseDescendentProcesses

Any process that appears in the task manager can be closed in this fashion.

2)    To open a new page or a new browser

The following command can be used to open a web page through internet explorer

Dim IE
   Set IE = CreateObject (“Internet Explorer.Application”)
   IE.visible = True
   IE.Navigate “www.yahoo.com

3)    To Open a database connection ( assuming that the database is Oracle)

    Dim oconn
    Set oconn = CreateObject ("ADODB.Connection")
    On Error Resume Next
    oconn.Open "Provider=OraOLEDB.Oracle.1; Data Source="<SID>"; User Id=<User Id>; Password=<Password>"

The below given code is optional but can be used for error handling purposes. This can be employed to exit from the run in case the connection to database cannot be established
   
    If Err. Number <> 0 Then
       Reporter.ReportEvent MicFail,"Error","  "& Err. Description & ".Exiting Run"
                Set oconn = Nothing
                Err. Clear  
                Call ExitRun (1)    
    End if

In automated regression testing, it is required to generate log files, results files etc. for verification purposes. In this section let’s discuss the techniques with which this interaction is possible with QTP.

4)    To add messages to the log file.

The following common function can be used for the same. The input to this function will be the message to be written to the log

Public Sub s_cu_LogMsg (str_message)
    Dim obj_fso, obj_Log_File
    Environment. Value ("Env_Log_File") = “C:\QuickTestPro\Log.txt”
    Set obj_fso = CreateObject ("Scripting.FileSystemObject")
    If Not obj_fso.fileexists (str_log_filename) Then
               Set Obj_Log_File = obj_fso.CreateTextFile(Environment.Value("Env_Log_File"), True)
            Obj_Log_File.WriteLine("Log Started on " & Now)
            Obj_Log_File.WriteLine(str_message)
            Obj_Log_File.Close
   Else   
          Set obj_Log_File = obj_fso.OpenTextFile(Environment.Value("Env_Log_File"),8, True)
          Obj_Log_File.WriteLine(str_message)
          Obj_Log_File.Close
   End If
  End Sub



5)    To add/Create an excel sheet in a particular location.

The XL files thus created can be used to store the results of the run, the input data and output data if any etc. This is the most suited form of storing and displaying the results of a run.

‘Give the sheet a name
            Str_name = "Regression_Testing”
            Str_Path="C:\quicktestpro"

            'Create an object of type excel application
            Set Obj_Excel_App = CreateObject("Excel.Application")
            Obj_Excel_App.DisplayAlerts = False
            ‘Save the workbook in the path specified
Set obj_wkb = Obj_Excel_App.Workbooks.Add()
   obj_wkb.SaveAs  Str_Path & "\" & Str_name &".xls"
   obj_wkb.close
            Set obj_wkb = Nothing
        
         NB: - The folder location should be already present. The Excel file will be created in the given location

         Tip: - It’s always advisory to choose the name of the sheets and columns present inside the XLS to be in a single line or separated by ‘_’ character. If you chose a name separated by blanks (say – “Reg Test”), QTP will automatically convert the names to be separated by ‘_’ values. So a mismatch in the given names and the created names will lead to run time errors in some cases.

6)    To access an already existing excel file in the given location

Str_path="C:\quicktestpro\Results.xls"
Set obj_XLApp = CreateObject ("Excel. Application")
obj_XLApp.DisplayAlerts = False
Set obj_excel_wkb = obj_XLApp.Workbooks.Open (Str_path)
obj_excel_wkb.Save

NB: - This method will not open the excel sheet in front of the user. But QTP will be able to read or write into the excel file present in the given location.
   
7)    To display the name of sheets in the above accessed excel sheet.

IntTotalsheet = obj_excel_wkb.Sheets.Count
For intcount = 1 To IntTotalsheet
       StrSheetName = obj_excel_wkb.Worksheets (intcount).Name
       Msgbox StrSheetName        
Next

NB: - Usually Msgboxes are not coded inside any automated script. This will defeat the purpose of automation since it needs user intervention to click on “OK” button in the Msgbox to continue the run. This is just employed for debugging purposes.

8)    To read/Write a value from/to a cell in a sheet in the above accessed excel file

‘To read
strValue = obj_excel_wkb.Worksheets(“<Sheet Name>”).Cells( R,C ).Value
‘To write
obj_excel_wkb.Worksheets (“<Sheet Name>”).Cells(R, C).Value = strValue
Where -
            R– Row number
            C – Column number
Tip: - If you want all the column names (headers), get all the cell values with R = 1.

9)    To clear values in a sheet for reusing the sheet

obj_entity_wkb.WorkSheets(“<Sheet Name>”).Range("2:1000,2:2").Clear
obj_excel_wkb.save

10) To delete unwanted files in the specified location

Strfile_path = "C:\quicktestpro\Tempfile.xls" - -The path of the file
Set obj_fso = CreateObject ("Scripting.FileSystemObject")

If obj_fso.fileexists(strfile_path) Then
                        Set objDt=obj_fso.Getfile(Strfile_path)
                        objDt.Delete
                        If Err.Number<>0 Then
                                    Reporter.ReportEvent MicFail,"Error”, “Failed to delete the file”
                                    Call Exitrun(1)
                        End If
End If

11)       To check for and remove special characters from a given string

To do the same, we have to know the ascii value of each character inside the string.
The built in function ASC will return the ascii value of any character. Then check if the ASCII falls in the range of special character ASCII’s.

ASCII of common alphabets (capital and small letters) fall in this range –
32, 48 – 57, 65-90, 97-122

ASCII of special characters fall outside the above range –
1 – 31, 33- 47, 58- 64, 91- 96, 123 - …

We can make use of a function to do the same. Inputs to this function will be the Input string, Output string (empty) and a Boolean variable which returns true or false.   

Public Sub s_cu_remove_special_characters (strInput, byRef strOutput, byRef boolSpecialCharExists)

    Dim strCurrChar
    Dim strReplaceChar
    Dim index
   
    'Set the Output variable to the same as input
    strOutput = strInput
   
    'Set the character that will replace special characters
    strReplaceChar = ""
   
      For index = Len (strInput) To 1 Step -1
            strCurrChar = Asc(Mid(strInput, index, 1))
            If ((strCurrChar < 48) and (strCurrChar<> 32)) _
                         Or ((strCurrChar > 57) and (strCurrChar< 65)) _
             Or ((strCurrChar > 90) and (strCurrChar < 97)) _
                         Or (strCurrChar > 122) _
Then
            boolSpecialCharExists = True
strOutput = Left(strOutput, index - 1) + strReplaceChar +
                                            Right (strOutput, Len (strOutput) - index)
            End If
    Next
End Sub

12) To generate a random number

In some cases we may need to store the results files generated during run time in the same folder. That time the file names have to be appended wit ha random number so that duplicate file names are not present. For this, the randomize function can be made use

'Use randomize function to initialize the random function
Randomize
strFileName = strFileName & “_” & Cstr (1000 * Rnd)

The file names can also be made unique by making use of the following logic
strFileName = strFileName &”_” & Day (Now) & "_" & Month (Now) & "_" & Year (Now) & "_" & Hour (Now) & "_" & Minute (Now) & "_" & Second (Now)

A combination of the above two methods can also be employed if the file generation frequency is that rapid.


Section II

Datatable is one of the significant parts of QTP tool. Datatable allows us to supply the input data for testing and store the output values and Test results in an excel format. In this section we can discuss the various methods that can be used for working with datatables effectively during run time.


1)    To retrieve values from a particular cell in datatable

‘First set the row from which data needs to be retrieved.
Datatable.GetSheet(“<Sheet Name>”).SetCurrentRow  <Row Number>

‘Get the value in a variable
strValue = Datatable.Value("<Column Name>","<Sheet Name>")
Or
strValue = Datatable.Value(<Column Number>,"<Sheet Name>")

2)    To create sheets in the datatable and add parameters to it

The following function can be made use of to achieve the same. The input Parameters to this function will be: Sheet Name, Comma separated parameter names

Public Sub s_cu_CreateSheet(str_Sheet_Name, str_Params)
        Dim arr_Params
        Dim str_Param_Name
        arr_Params = Split (str_Params, ",", -1, 1)
        Datatable.AddSheet str_Sheet_Name
        For Each str_Param_Name in arr_Params
                Datatable.GetSheet(str_Sheet_Name).Addparameter str_Param_Name, ""
        Next
End Sub

3)    To add/remove a column to a particular sheet in the datatable

Datatable.GetSheet(“<Sheet Name>”).Addparameter “<Column Name>”, ""
Datatable.GetSheet(“<Sheet Name>”).Deleteparameter “<Column Number>

4)    To export the whole datatable values to an excel sheet

Datatable.Export “C:\QuickTestPro\Results.xls”

NB: - This is the easiest method for exporting the datatable to an excel file. For this method to work, the folder should be already present .The excel file will be automatically created. If an excel file with the same name exists in the location, it will be over written.

5)    To conditionally export some sheets to an excel sheet.

This method can be employed if just one or two sheets out of the datatable needs to be exported.

strDt_path="C:\QuickTestPro\Results.xls"

            For intcount=1 To DataTable.GetSheetCount    
                        StrSheetName=DataTable.GetSheet (intcount).Name     
If Ucase (Trim (StrSheetName)) = “RESULTS” Then
                                    DataTable.ExportSheet strDt_path, intcount
End If
             Next

6)    To import values from an excel file to the datatable

Datatable.Import “C:\QuickTestPro\InputSheet.xls”

Tip: - This method is very useful in a batch run of scripts to take the output of a previous run to use as the input of the current run.

7)    To count the number of columns in a sheet

intColumnCount = DataTable.GetSheet ("<Sheet Name>").GetParameterCount

8)    To count the number of rows in a sheet

There is no inbuilt function to achieve this. You can employ the following logic for counting the rows. The non blank rows will be counted.

Public Function fn_cu_GetDTSheet_RowCount (strSheetName)

         intInitialRow = DataTable.GetSheet (strSheetName).GetCurrentRow
         DataTable.GetSheet (strSheetName).SetCurrentRow (1)
         int_col_count = Datatable.GetSheet(strSheetName).GetParameterCount()
         boolRowsPresent = True
         While (boolRowsPresent)
                     boolRowsPresent = False
                     For intColNum = 2 To int_col_count
                                 If Trim (DataTable.Value (intColNum,strSheetName)) <> ""
                                 And Not Isnull (DataTable.Value (intColNum, strSheetName)) Then
                                             intNumOfRows = intNumOfRows + 1
                                             boolRowsPresent = True
                                             Exit For
                                 End If
                     Next

                     If (boolRowsPresent = True) Then
                                 DataTable.GetSheet (strSheetName).SetNextRow
                                 intCurrRow = DataTable.GetSheet (strSheetName).GetCurrentRow  
                                 If intCurrRow = 1 Then
                                             boolRowsPresent = False
                                 End If
                     End If   
         Wend
         fn_cu_GetDTSheet_RowCount = intNumOfRows
         DataTable.GetSheet (strSheetName).SetCurrentRow (intInitialRow)
End Function

The input to this function will be just the sheet name .The function can be called from inside a loop so that the row count of all the sheets in the datatable can be found and stored in variables.

SECTION III

In this section we can discuss the various methods that can be used for improving the script performance.

1)    To make QTP wait if the application cursor is in busy state.

This is needed in many cases since after the click of a button or a set operation, the application will switch to a busy state. At that time if QTP tries to perform the next operation in line, it will error out since all objects will be in a disabled state. In such cases the following piece of code will be of great use. The input to function will be the main window of the application.

            Public Sub s_cu_Sync (obj_java_window)

‘To prevent the sync operations from appearing in the QTP results file
Reporter.Filter = rfDisableAll
'Wait till the cursor type changes to something else than busy state
While (obj_java_window.GetROProperty("cursor_type") = "3")
                        Wait 2
Wend
Reporter.Filter = rfEnableAll
            End Sub
Call this function after the click/set operation.
Eg: - s_cu_Sync Javawindow (“Oracle Applications”)

2)    To load the user defined environment variables from a text file (ini file)

‘Store the path in a variable
Str_Def_Env_File= “C:\quicktestpro\Environment.ini”
‘Load from the file during runtime
Environment.LoadFromFile Str_Def_Env_File
           
You need to create the text file with “.ini” extension. The environment values should be defined inside the file. Say Environment (“Wait_time”) = 30. 

3)    To perform a conditional re-login ( Resume Functionality)

In many cases the logging in to the application takes a lot of time. Taking into consideration the performance of the script, it’s always suggested to do the login action as minimum as possible .Re-login needs to be performed only in those cases where the errors or pop ups in the previous iterations is stopping the script from continuing the current iteration. The current iteration may also error out due to errors or wrong inputs in the previous iteration. In order to avoid this we should close all open browsers and do a re-login to the application and start the next iteration with a fresh page. The following simple logic can be used for this. The following code should be present in the top of the main action (main action – is the action which has the setting as -Run on all rows)

'On first iteration add an additional column in the main sheet of datatable
If Environment.Value("ActionIteration")=1 Then
   Datatable.GetSheet("Action_Main").AddParameter "Iteration_Completed", ""
End If

'Resume Functionality
If Environment. Value ("ActionIteration") <> 1 Then
            intcurrentrow = (Environment.Value("ActionIteration"))
            ‘Check if the previous iteration completed till the end
            DataTable.GetSheet ("Action_Main").SetPrevRow
            If Trim (Datatable.Value("Iteration_Completed","Action_Main"))= "" Then
                 Datatable.Value("Iteration_Completed","Action_Main") = "No"
                 SystemUtil.CloseProcessByName ("iexplore.exe")
                 SystemUtil.CloseProcessByName ("excel.exe")
     Wait (5)
                ‘Call the common login action
                 Call RunAction("Login", oneIteration)
            End If        
            Datatable.GetSheet("Action_Main").SetCurrentRow(intcurrentrow)                                                           
End If

If the script completed the current iteration, close all open windows except the main window so that the next iteration can resume from the main window without performing a relogin.It is also needed to do the following operation at the last line of the main action
           
       (Datatable.Value("Iteration_Completed","Action_Main"))= "Yes"

4)    Decreasing the unwanted wait times.

A QTP script should simulate the user actions without any wastage of time. It should not wait unnecessarily in “exist” conditions and increase the script run time. QTP has an inbuilt sync time which is defaulted to 20 secs. So even if the object is not present in the front end, QTP will wait for 20 secs before displaying a fail or pass message. In some cases it may be needed to change the built in sync time of QTP to make the script wait for a very less time. You can change it by using the following logic.

‘In the start of the action, create an object of QTP
Set App = CreateObject ("QuickTest.Application")
‘Store the current sync time in a variable
intSync = App.Test.Settings.Run.ObjectSyncTimeOut
‘Reduce the wait time to just 5 ms
App.Test.Settings.Run.ObjectSyncTimeOut = 500
………………………………………
‘To reset the wait time to the default value
App.Test.Settings.Run.ObjectSyncTimeOut = intSync


No comments:

Post a Comment