Beruflich Dokumente
Kultur Dokumente
Training Guide
Release 5.2.0
Please direct questions about Testpartner or comments on this document to: TestPartner Technical Support Compuware Corporation One Camp Martius Detroit, MI 48226-5000 1-800-538-7822 Outside the USA and Canada, please contact your local Compuware office or agent.
Copyright 1999 Compuware Corporation. All rights reserved. Unpublished rights reserved under the Copyright Laws of the United States. U.S. GOVERNMENT RIGHTS: Use, duplication, or disclosure by the U.S. Government is subject to restrictions as set forth in Compuware Corporation license agreement and as provided in DFARS 227.7202-1(a) and 227.7202-3(a) (1995), DFARS 252.227-7013(c)(1)(ii)(OCT 1988), FAR 12.212(a) (1995), FAR 52.227-19, or FAR 52.227-14 (ALT III), as applicable. Compuware Corporation. THIS MATERIAL CONTAINS CONFIDENTIAL INFORMATION AND TRADE SECRETS OF COMPUWARE CORPORATION. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF COMPUWARE CORPORATION. Compuware, Reconcile, QARun, TestPartner, QADirector, TrackRecord, QAHiperstation+ and QAHiperstation are trademarks or registered trademarks of Compuware Corporation.
All other company or product names are trademarks of their respective owners. Doc. CWQAD2.0A October 22, 1999.3
CHAPTER 1 -- OBJECT MAPPING ............................................................................. 8 INTRODUCTION TO OBJECTS .............................................................................................. 8 DETERMINING WHICH OBJECTS TO MAP.......................................................................... 9 MODIFY RECORD OPTIONS ............................................................................................. 10 To modify the Record options.................................................................................... 10 MODIFYING ATTACH NAME OPTIONS............................................................................. 12 MANAGE ATTACH NAME PROFILES ................................................................................ 14 Create an Attach Name Profile................................................................................... 14 Activating an Available Attach Name Profile............................................................ 23 Change the Order of an Attach Name Profile ............................................................ 23 Deactivating an Attach Name Profile......................................................................... 24 TIPS FOR NAMING ATTACH NAME PROFILES.................................................................. 26 COMPARING ATTACH DATA ENTRIES ............................................................................. 28 Selecting Attach Data from the Object Browser........................................................ 28 Selecting Attach Data in the Attach Data Compare dialog box................................. 30 MODIFY THE COMPARE ATTACH DATA COLORS ............................................................ 31 To modify the compare attach data colors ................................................................. 31 EXERCISE 1 OBJECT MAPPING ........................................................................... 34 CHAPTER 2 SCRIPT MODULARITY ....................................................................... 40 RUN() ............................................................................................................................. 41 EXERCISE 2 SCRIPT MODULARITY ................................................................... 42 CHAPTER 3 SCRIPT LOGIC ...................................................................................... 46 PROCEDURES .................................................................................................................. 46 Subroutines................................................................................................................. 46 Functions .................................................................................................................... 47 ARGUMENTS ................................................................................................................... 47 Passing Arguments by Reference............................................................................... 47 Passing Arguments by Value ..................................................................................... 48 CONTROL FLOW STATEMENTS........................................................................................ 49 If.Then .................................................................................................................... 49 If.Then.Else ........................................................................................................ 50 Select Case ................................................................................................................. 51 LOOP STATEMENTS......................................................................................................... 52 DoLoop................................................................................................................... 52 ForNext................................................................................................................... 53 WhileWend............................................................................................................. 54 THE EXIT STATEMENT .................................................................................................... 54 EXERCISE 3 SCRIPT LOGIC .................................................................................. 55 CHAPTER 4 VARIABLES, ARRAYS & COLLECTIONS ...................................... 57
VARIABLES ..................................................................................................................... 57 Naming Conventions.................................................................................................. 57 Types of variables ...................................................................................................... 57 ARRAYS .......................................................................................................................... 59 Declaring Arrays ........................................................................................................ 59 Specifying Limits ....................................................................................................... 59 COLLECTIONS ................................................................................................................. 60 Adding to a Collection ............................................................................................... 60 Removing an item from a collection .......................................................................... 60 Returning Items in a collection .................................................................................. 61 Counting a collection ................................................................................................. 61 OPTION EXPLICIT............................................................................................................ 61 VARIABLE SCOPE ........................................................................................................... 62 CHAPTER 5 MODULES AND CLASS MODULES .................................................. 66 MODULES ....................................................................................................................... 66 Adding a Module........................................................................................................ 66 Using A module ......................................................................................................... 67 SHARED MODULES ......................................................................................................... 68 Adding a Shared Module............................................................................................ 68 Using a Shared Module .............................................................................................. 68 CLASS MODULES ............................................................................................................ 69 Adding a Class Module .............................................................................................. 69 Using a Class Module ................................................................................................ 69 EXERCISE 5 MODULES AND CLASS MODULES ................................................. 71 CHAPTER 6 ALIAS MAPPING................................................................................... 73 USING ALIAS MAPPING .................................................................................................. 74 ADDING ALIAS MAP ENTRIES ......................................................................................... 75 MODIFYING ALIAS MAP ENTRIES ................................................................................... 77 DELETING ALIAS MAP ENTRIES ..................................................................................... 78 EXERCISE 6 ALIAS MAPPING.................................................................................. 79 CHAPTER 7 IMAGE MAPPING AND TEXT SELECTS ........................................ 83 IMAGE MAPPING ............................................................................................................. 83 TEXTSELECTS ................................................................................................................. 89 EXERCISE 7 IMAGE MAPPING AND TEXT SELECTS ....................................... 91 CHAPTER 8 TEST DATA HANDLING ..................................................................... 93 TESTDATA FILES ............................................................................................................ 93 ACCESSING A STANDARD CSV FILE ............................................................................... 94 ACCESSING AN EXCEL SPREADSHEET ............................................................................. 96 ACCESSING A CSV FILE WITH COLUMN HEADINGS ........................................................ 98 EXERCISE 8 TEST DATA HANDLING .................................................................. 103 4
CHAPTER 9 MULTIPLE EVENTS........................................................................... 110 WAIT EVENTS ............................................................................................................... 110 WHENEVER EVENTS ..................................................................................................... 111 EXERCISE 9 MULTIPLE EVENTS.......................................................................... 115 CHAPTER 10 CAPTURING DATA .......................................................................... 119 IDENTIFY ICON .............................................................................................................. 119 USE OF THE STOP COMMAND........................................................................................ 121 OBJECT SELECTION SCREEN ......................................................................................... 122 CAPTURETEXT METHOD............................................................................................... 124 EXERCISE 10 CAPTURING DATA.......................................................................... 126 CHAPTER 11 ERROR HANDLING.......................................................................... 128 DEFINING AN ERROR HANDLING SUBROUTINE ............................................................. 129 ERROR PROPERTIES ...................................................................................................... 130 EXIT FROM AN ERROR FUNCTION ................................................................................. 130 THE ERROR HANDLER IN A SHARED MODULE .............................................................. 131 CHAPTER 12 USER DIALOGS AND SCRIPT DEBUGGING.............................. 136 MSGBOX ...................................................................................................................... 136 INPUTBOX .................................................................................................................... 138 DEBUGGING SCRIPTS .................................................................................................... 139 USER FORMS ................................................................................................................ 140 ACTIVATION OF A USERFORM ...................................................................................... 149 EXERCISE 12 USER DIALOGS AND SCRIPT DEBUGGING............................. 150 CHAPTER 13 USER ID/PASSWORD ENCRYPTION ........................................... 152 SWITCHING LOGGING OFF ............................................................................................ 152 ENCRYPTION AND DECRYPTION ROUTINES .................................................................. 152 STORING AND RETRIEVING FROM THE REGISTRY ......................................................... 154 EXERCISE 13 USER ID/PASSWORD ENCRYPTION .......................................... 156 CHAPTER 14 FILE HANDLING............................................................................... 158 MICROSOFT SCRIPTING RUNTIME ................................................................................. 158 THE FILESYSTEMOBJECT ............................................................................................. 159 THE TEXTSTREAM OBJECT ........................................................................................... 160 EXERCISE 14 FILE HANDLING.............................................................................. 162 CHAPTER 15 USING SQL ......................................................................................... 165 MICROSOFT ACTIVEX DATA OBJECTS ......................................................................... 165 CONNECTION AND RECORD SET OBJECTS..................................................................... 165 EXERCISE 15 USING SQL ........................................................................................ 167 5
CHAPTER 16 SCREENSHOTS ................................................................................. 169 PRINTSCRN ................................................................................................................... 169 STORING IN FILES ......................................................................................................... 169 EXERCISE 16 SCREENSHOTS ................................................................................ 171 APPENDIX A - SOME EXTRA NOTES ................................................................... 174 WORKING WITH LISTS AND COMBO BOXES .................................................................. 174 SCROLLBARS ................................................................................................................ 174 CHECKBOXES................................................................................................................ 175 LOADING AN APPLICATION ........................................................................................... 176 THE CURRENTLY ACTIVE WINDOW .............................................................................. 176 SEARCH FUNCTIONS ..................................................................................................... 177
10
3. The attach name details may be modified as described in the following section Modifying Attach Name Options. 4. Optionally, click Save As to save your settings as a group name
5. Click OK to close the Record Settings dialog box 6. Click OK on the options dialog box to apply your changes and close the dialog box. Click Cancel to close the dialog box without applying your changes.
11
Set to Create new, Use existing, TestPartner will automatically create and record an Object Map entry when attaching to any object during recording, as long as the
12
object does not already have an entry in the Object Map. If an object already has an Object Map entry, a map entry will not be created for the object, but the original map entry in the database will be recorded. Set to Use existing, TestPartner will use an existing Object Map entry if one exists for the object being recorded. If a Map entry does not exist for the object, the raw attach name will be recorded. Set to Raw Attach Name to disable Object Map recording and only record raw attach names when attaching to objects during recording.
2. Manage Attach Name Profiles Click the Ellipsis button in the value field to display the Manage Attach Names Profiles dialog box, where you can create and manage how objects are recorded, and set properties of interest for each object type. This is detailed in the next section, Manage Attach Name Profiles. 3. Disable Attach Name Profiling Set to Yes to prevent TestPartner from using any currently active Attach Name profiles. This setting lets you turn profiling on and off without having to go to the Manage Attach Name Profiles and move profiles to and from the Active and Available Profiles lists. 4. Flash Rate Per Second Type a value to set the number of times per second the surrounded border flashes when TestPartner is locating an object. You locate an object by clicking the Locate button when viewing details for the object's map or attach name entry, or in the Identify or Locate Image Map dialog boxes. 5. Maximum Number of Flashes Type a value to set the maximum number of times the surrounded border flashes when TestPartner is locating an object. You locate an object by clicking the Locate button when viewing details for the object's map or attach name entry, or in the Identify or Locate Image Map dialog boxes. The maximum number of flashes setting and the Flash rate per second can be used to determine how long the surrounding border will flash when TestPartner locates an object. For example, a setting of five for the Flash Rate per Second with a Maximum Number of Flashes set to fifteen would allow the object map locator's flashing border to flash for a maximum of three seconds
13
To access the Manage Attach Name Profile dialog box 1. Select Tools | Options. 2. In the outline view, click Record. 3. The Record options display in the panel on the left and the Timing, Attach Name, and Hotkeys sub-categories display in the outline view below Record. 4. In the outline view, click Attach Name 5. In the options panel, select Manage Attach Name Profiles, then click the ellipsis button . The Manage Attach Name Profiles dialog box displays.
14
To create and name an Attach Name profile 1. In the Manage Attach Name Profiles dialog box, click New. The New Profile dialog box displays.
2. In the Name Field, type the name for the Attach Name profile you want to define. You can use any combination of characters and numbers when naming a profile. Spaces are also allowed. The profile should be given a name that gives its users an idea of the profile's use. See section "Tips for Naming Attach Name Profiles" for more information on tips for naming Attach Name profiles.
15
3. To base the new profile on an existing profile, selecting an existing profile name in the Copy From list box. Select <Default Profile> if you do not want to base the new profile on an existing profile. 4. Click OK. The Attach Name Profile dialog box displays.
To define attach data configuration criteria for the Attach Name profile 1. Select the Domain extensions that will apply to the Attach Name profile. In the Include column, select the check box of the extension(s) you want to set object type and properties of interest settings for. Extensions include: COM Objects - Includes the App and COMObject object types, which can be recorded when the recording domain is set to COM. HTML Includes HTML Object types derived from Standard Controls, such as HTMLButton, HTMLCheckbox, etc. Also includes non-standard controls for HTML, such as HTMLBrowser, HTMLTable, etc., and Netscape specific controls such as NSToolbar. HTML object types begin with the prefix HTML in TestPartner script. 16
Java Select this check box to customize how TestPartner records Java controls such as JavaEditBox, JavaListBox, etc. Java object types begin with the prefix Java in TestPartner script. Navision For users of Cronus' Navision Attain product, select this check box to customize how TestPartner records Navision controls, including NAVSubForm and NAVMatrixBox. Navision object types begin with the prefix NAV in TestPartner script. Standard Controls Select this check box to customize how TestPartner records base objects types such as Window, Button, ListBox, etc. VisualBasic Select this check box to customize how TestPartner records its set of objects types specific to VisualBasic. VisualBasic objects begin with the prefix VB.
2. Select the object types that will apply to the selected domain extensions. In the Attach Name Profile dialog box, click the Types tab. The Types tab displays a list of each object type that is a member of any selected domain extensions.
17
In the Include column, click the check box of each object type you want to be part of the profile. Each selected object type becomes part of the profile. Note: If editing the profile, you can also click selected check boxes to deselect them. Click the Record As column for each selected object type, then select from the list the preferred method to record that type. There are three choices: Raw Attach Name TestPartner will record this object as a raw attach name. Properties recorded for the object may include the properties of interest selected for the object type. Prompt For Value When selected, TestPartner will prompt you to enter an object map name for an object, unless the object already has an Object Map entry in the database. TestPartner supplies a default name which you can use. If an Object Map entry already exists, TestPartner will automatically use that entry. You can click Cancel when the prompt displays to use the raw attach name. Object Map Entry TestPartner will record this object as an object map entry based on Object Map recording guidelines. If an object map entry already exists for a recorded object, TestPartner will use the existing entry.
18
3. Select the applicable properties of interest for each object type selected. In the Attach Name Profile dialog box, click the Properties of Interest tab. The Properties of Interest tab displays two panes.
The left pane is the Properties pane. It shows all the properties for each object type selected. Each selected property has a check in the Include column. The right pane is the Types pane. It shows a list of the relevant object types for each selected property. These are the objects selected in the Types tab which have the selected property. In the Include column of the Properties pane, click the check box of the first property you want to be a property of interest for the selected object type. This selects the property for all types that include the property. You can also click a selected check box to deselect a property.
19
The Selected column changes to indicate how many of the object types the select property applies to as a property of interest. For example "1 of 2" means the property is a property of interest for 1 of the 2 selected object types. The word "All" means this property is a property of interest for all the object types in the Types pane. "None" means the property has not been selected as a property of interest for any of the objects in the profile. The Includes column of the Types panel selects properties on a type-by-type basis. Select the check box of object type you want the selected property to be a property of interest for. Note that the Selected column in the Properties pane changes if you select or deselect objects. To force a property as a property of interest for an object type, select the Always Use check box for the desired object type. Note that the Always Use check box only displays when the property is included. If the Always Use check box is not selected, the selected property of interest is recorded in script in accordance with TestPartner's properties of interest recording guidelines. Note: If editing the profile, you can also click selected check boxes to deselect them. Repeat the above for each property you want as a property of interest for the selected object types. Click OK to save your changes and return to the Manage Attach Name Profiles dialog box, or click Cancel to exit without saving your changes. You can also click Apply to record your changes immediately, or optionally click the Applications tab and continue defining the profile by specifying applications for an attach name profile.
4. You can also optionally specify applications on which the profile will operate. Each Attach Name Profile can be set to operate on specific applications. This feature allows you to record an object differently based on the application under test. The default is for a profile to work on all applications. 4.1 To access the Applications tab of the Attach Name Profile dialog box In the Manage Attach Name Profiles dialog box, select the profile you want to want to specify certain applications to operate on. You can select any profile from either the Active or Available column. Click the Edit button to access the Attach Name Profiles dialog box. 20
4.2 To add an application to the list Start the application you want to add to the list, if it is not currently running. After starting the application, switch back to the TestPartner application. To add the application to the list, click Identify. TestPartner is minimized, and the target application becomes visible. Position the mouse over any window or control in the application and click the left mouse button.
21
TestPartner is restored and the name of the application displays in the Applications list.
As an alternative to using Identify, you can click Browse Tree to select an attach name from the Object Selection window or Object Map to select an attach name from the existing Object Map entries. You can also click Add and enter the file name of the application in the Add Application dialog box. However, the application name entered must exactly match the application name. Note: You can also select an application from the Applications list and click Remove to remove it. Click OK to save your changes and return to the Manage Attach Name Profiles dialog box, or click Cancel to close exit without saving your changes. You can also click Apply to record your changes immediately.
5. Click OK to save your changes and exit to the Manage Attach Name Profiles dialog box, or click Cancel to exit without making any changes. In the Manage Attach Names dialog box, the created profile is added to the list of available profiles. 22
Click the Activate button . To activate all profiles from the Available list, click the Activate All button .
Repeat the above steps to activate other profiles from the Available list.
23
In the Manage Attach Name Profiles dialog box, select the profile in the Active list whose order you want to change. If the profile you want is not in the Active list, you can activate it from the Active list.
Click Move Up or Move Down to change the order of the selected profile. Click OK to save your profile changes or Cancel to exit without saving your changes.
24
Click OK to save your profile changes or Cancel to close the Manage Attach Name Profiles dialog box without saving your changes. Click OK to save your profile changes or Cancel to close the Manage Attach Name Profiles dialog box without saving your changes.
25
26
Examples HTML Extensions VisualBasic Controls Navision If you know that you'll want to always record some object types as raw attach names and others as Object Map entries, you may want to create profiles based on these recording options. In that case, consider creating two profiles; one with all the object types that are to be recorded as Raw Attach Names, one with all the object types to be recorded as Object Map entries. These profiles could be named Raw Attach Names and Object Map Entries
27
28
Perform one of the following: Right-click and select Compare Attach Data from the pop-up menu. Click the Compare Attach Data button on the toolbar. Select Tools | Compare Attach Data on the menu bar.
When both attach data entries you want to compare display in the Compare Attach Data dialog box, you can compare their differences. Each property for the entries and their values are shown, and significant properties for each are marked by a check next to the property in the Significant column. Color codes indicate the type of difference. The colors used can be set in TestPartner options for Compare Attach Data Colors. See the section "Modilfy the Compare Attach data Colors" below for details about what each difference and color code signify
29
1. Using the Identify Button In the desired pane of the Compare Attach Name dialog box, click Identify to select the object from the desktop. When you click Identify, a crosshair cursor displays, and window objects are highlighted as you move the mouse over them in the target application. When the control you want to add is highlighted, click the left mouse button. Click OK. Attach data and properties for the selected control are displayed in the selected pane of the Compare Attach Name dialog box.
2. Using the Browse Tree Button Click Browse Tree... to select the object whose attach name data you want to compare from a tree view of the current GUI or COM objects. The Object Selection window displays. In the Object Tree pane, choose the GUI or COM object you want to compare from the object tree. When you highlight an element in the object tree, its properties display in the Properties pane. If you don't see the Properties pane, click Properties on the toolbar. Click OK. Attach data and properties for the selected control are displayed in the selected pane of the Compare Attach Name dialog box.
30
Click Object Map... to select the object from the Object Map. When you choose Object Map..., the Browse for Object Map Entry window displays. Choose the object you want to check and click Insert. Attach data and properties for the selected control displays in the selected pane of the Compare Attach Name dialog box.
4. With an entry selected in each window pane the differences between the two entries may be viewed as described before.
31
In the option panel on the right, select the color option you want to change. You can set color combinations for the following: Different Values Text color used to indicate a value in the Values column that is different from the attach data being compared. Different Values Selected Text color used when a value that differs is selected in either Value column of the Compare Attach Data utility. Different Significance Background color used in the Significant column of the Compare Attach Data utility to indicate a difference in the significance state of a property between the attach data being compared. Different Significance Selected Background color used in the Significant column of the Compare Attach Data utility when an item in the Significant column is selected. Used to indicate a difference in the significance state of a property between the attach data being compared. Property is Missing Text color used to indicate that the property in the attach data being compared is missing. Property is Missing Selected Text color used to indicate that the property in the attach data being compared is missing, when the property entry that is not missing is selected. Property Doesn't Exist Color of the patterned lines that go through a row when a property only exists in the attached data being compared.
Click the ellipsis button ( . . . ) next to the selected color option. TestPartner displays the Windows Color dialog box.
32
Use the Windows Color dialog box to set the desired color. Click OK to set the color for the selected color option. The color value for the selected color option changes. Color values are represented by their hexadecimal value. Repeat the above for any other Compare Attach Data Color options you want to change. Note: If at any time you want to revert to the original system colors to indicate differences between compared attach data, click the Restore Defaults button. Click OK to apply your changes and close the dialog box. Click Cancel to close the dialog box without applying your changes.
33
Target Application: QADemo Web Instructions: STEP 1: STEP 2: STEP 3: Create an Attach Name Profile called QADemo Web . Select HTML and Standard Controls extensions Set the Types HTMLEditBox , HTMLRadioButton, HTMLButton to Object Map Entry. Set the Type Window to Prompt for Value. Activate the attach Profile. Record loading the QADemo Web application, signing in, select add cars, input an entry to every field in the add cars windows and then exit the application. Select the Object Map asset and examine the objects stored in the map. Rename the Edit Field entries to have meaningful names. Then record the add car option in QADemo again and compare the script with the earlier script.
STEP 4: STEP 5:
STEP 6: STEP 7:
34
35
36
The web address for QADemo Web is: http://127.0.0.1/~qademo The user id and password are dtl and pass. From the File menu select Main Options From the list select Add Car Fill in all fields and checkboxes
37
Select Add and then Close the browser. Stop Recording STEP 6: Examine the object Map
38
Testpartner script recorded before Object Renames: ' Attach to Caption='QADemo - Add Car' HTMLBrowser("Caption='QADemo - Add Car'").Attach HTMLEditBox("HTMLEditBox_0002").SetText "Car1" HTMLEditBox("HTMLEditBox_0003").SetText "Ford" HTMLEditBox("HTMLEditBox_0004").SetText "3000" HTMLEditBox("HTMLEditBox_0005").SetText "1999" HTMLEditBox("HTMLEditBox_0006").SetText "3" HTMLEditBox("HTMLEditBox_0007").SetText "Blue" HTMLEditBox("HTMLEditBox_0008").SetText "3000" HTMLEditBox("HTMLEditBox_0009").SetText "15" HTMLEditBox("HTMLEditBox_0010").SetText "1" HTMLCheckBox("Name=chkRadio").Click Testpartner script recorded after Object Renames: ' Attach to Caption='QADemo - Add Car' HTMLBrowser("Caption='QADemo - Add Car'").Attach HTMLEditBox("Add Car Window Reference Edit").SetText "Car2" HTMLEditBox("Add Car Window Make Edit").SetText "Ford" HTMLEditBox("Add Car Window Engine Size Edit").SetText "3000" HTMLEditBox("Add Car Window Year Edit").SetText "1999" HTMLEditBox("Add Car Window Doors Edit").SetText "3" HTMLEditBox("Add Car Window Color Edit").SetText "Blue" HTMLEditBox("Add Car Window Cost Edit").SetText "3000" HTMLEditBox("Add Car Window DealerDiscount Edit").SetText "15" HTMLEditBox("Add Car Window Quantity Edit").SetText "1" HTMLCheckBox("Name=chkRadio").Click
39
A driver script runs a setup script to run an application or open a Web page. The driver script then launches the first test script, which tests the functions or user interface for that test site and logs the results. When the first test script finishes running, the driver script advances the application to the next test point and launches the next test script, which again runs the appropriate tests for that site. Since one driver script can run any number of test scripts, you can add or modify test scripts as self-contained modules. A driver script uses the Run command to run compiled scripts. A well-designed test script returns the target application to the original test point before completion. This ensures that: Driver scripts can always pick up from where they left off. You can add or remove tests at a test site without modifying the driver path.
40
Run()
Runs another script from this script. This script is suspended until the other finishes. Syntax: Run( "scriptname" ) Operation: This command runs the script specified by "scriptname". The calling script is suspended until "scriptname" has finished processing. Then it resumes from the line following the Run command. Examples: Sub Main() Run ("AppLoad") Run ("AppClearDB") Run ("AppAddData") Run ("AppVerifyData") End Sub
41
Instructions: STEP 1: Create a new script named EX02 Record the process of starting QADemo Web (http://127.0.0.1/~qademo), signing on to the application (dtl, pass), closing the New window, Selecting ResetDatabase from the menu, Selecting Logoff from the menu and closing the browser. Verify the script plays back. STEP 2: Cut the instructions from EX02 for starting and signing on to QADemo Web, and paste them into a new script called Signon. STEP 3: Cut the instructions from EX02 for closing QADemo, and paste them into a script called Shutdown. STEP 4: Cut the instructions from EX02 for clearing the database and paste them into a script called ClearDataBase. STEP 5: Insert Run commands into EX02 to run the new scripts Startup, Shutdown., and ClearDatabase. Verify the new script executes without error.
42
43
Shutdown Script
44
45
Subroutines
A subroutine is a block of statements that carries out a well defined task. The block of statements is placed in a pair of Sub/End Sub statements and can be invoked by name. Sub ShowDate() MsgBox Date() End Sub A subroutine would normally be more complicated than the above. This subroutine can be invoked by calling it: Call Showdate() Or it can be invoked by just using the name: ShowDate() Subroutines may also accept parameters separated by commas: Call Subroutine (Param1, Param2,Param3,.) Altering the above ShowDate subroutine to accept a parameter of a number of days and to display the date of today plus that number of days we get: Sub ShowDate ( Count as Integer) MsgBox Date() + Count End Sub To call this we can now use:
46
ShowDate ( NumDays) Where NumDays is an Integer variable containng the number of days to add to today. While a Subroutine can accept parameters it can not return a value, in order to return a value we must use a Function.
Functions
A function is similar to a subroutine, but a function returns a result. Subroutines perform a task and don't return a value to the calling program; functions typically carry out calculations and report the result. A function is a block of code between Function/End Function statements. Also as a Function returns a value it must have a type. Changing our ShowDate subroutine above to be a function that returns a date we would have the following: Function NewDate (Count as Integer) As Date NewDate = Date() + Count End Function Note how the second line of the above function returns a value, this is achieved by assigning the return value to the function name. We would invoke this function as follows: NextDate = NewDate( NumDays)
Arguments
Arguments (parameters) can be passed to procedures in two ways, by reference (the default) where the address of the original variable is passed and the procedure could change the original variable. The other way is by value, where a copy of the argument is passed and the procedure can not alter the original value.
47
End Function Dim A As Integer, B As Integer A= 10 B= 2 Sum = Add (A,B) Debug.Print A Debug Print B Debug.Print Sum The above code will give the results: 0 0 12 In general you only pass arguments by reference if the called procedure has a need to alter its value, this is not a safe method of passing parameters and should not be used unless necessary. When passing an argument by reference, the argument type must match the declared type (Both are Integer in the above example). If they do not match then an error message will be generated. If in the above example A was defined : Dim A As Single Then we need to convert this value to integer. This can be done as follows: Sum = Add (Cint(A),B) A second method is to let VB to automatically convert the value, this is achieved by enclosing the argument in parenthesis. Sum = Add ((A),B)
Add = Num1 + Num2 Num1 = 0 Num2 = 0 End Function Dim A As Integer, B As Integer A= 10 B= 2 Sum = Add (A,B) Debug.Print A Debug.Print B Debug.Print Sum The above code will give the results: 10 2 12 The code in the function, which assigns zero to the arguments, has no effect on the original variables.
If.Then
The If structure can have a single line or multiple line syntax: If condition Then statement If condition Then statement End If Examples: If Month (date) = 1 Then Year = Year + 1 If Month (date) = 1 Then Year = Year + 1 End If
49
If.Then.Else
The IfThenElse statement executes one block of statements if the condition is True and another if False. If condition Then statement block 1 Else statement block 2 End If If the condition is true then statement block 1 is executed, if the condition is false then condition block 2 is executed. Another variation of the IfThenElse statement uses several conditions with the ElseIf keyword. If condition1 Then Statement block 1 ElseIf condition2 Then Statement block 2 ElseIf condition 3 Then Statement block 3 Else Statement block 4 End If You can have any number of ElseIf clauses. The conditions are evaluated from the top, if one of them is True then the corresponding block of statements is executed. The Else clause will be executed if none of the previous expressions are true. Example: Score = InputBox("Enter Score") If Score < 50 Then Result = "Failed" ElseIf Score < 75 Then Result = "Pass" ElseIf Score < 90 Then Result = "Very Good" Else Result = "Excellent" End If
50
Select Case
The Select Case structure compares one expression to different values. The advantage over multiple IfThenElse statements is that it makes the code easier to read and maintain. Select Case expression Case value 1 Statement block 1 Case value 2 Stratement block 2 . . . Case Else Statement block End Select Example: Select Case WeekDay(Date) Case 1 DayName = "Monday" Message = "Have a nice week" Case 6 DayName = "Saturday" Message = "Have a nice weekend" Case 7 DayName = "Sunday" Message = "Did you have a nice weekend" Case Else Message = "Welcome Back" End Select Some Case statements can be followed by multiple values, which are seperated by commas. The following demonstrates this: Select Case WeekDay(Date) Case 1 DayType = "Workday" Message = "Have a nice week" Case 2, 3, 4, 5 DayType = "Workday" Message = "Have a nice weekend" Case 6, 7 DayType = "Weekend"
51
Message = "Have a nice weekend" End Select The above structure does not contain a Case Else statement because all possible values are handled by the Case statements.
Loop Statements
Loop statements allow you to execute one or more lines of code repetitively. There are three loop statements: DoLoop ForNext WhileWend
DoLoop
The DoLoop executes a block of statements for as long as a condition is True. There are two variations using keywords While and Until to specify how long the statements are executed. To execute a block of statements while a condition is true use: Do While condition Statement block Loop To execute a block of statements until the condition becomes true use: Do Until condition Statement block Loop A DoLoop can execute any number of times as long as condition is True. The number of iterations need not be known before the loop starts. If condition is initially False the statements may never execute. Another variation of the Do loop always executes the statements first and evaluates the condition after each execution, this ensures the statements will be executed at least once. Do Statements Loop While condition
52
ForNext
Unlike the Do loop the ForNext loop requires that you know how many times the statements in the loop will be executed. The ForNext loop uses a variable (called the loop counter) that increases or decreases in value during each repetition of the loop. The syntax is as follows: For counter = start To end [step increment] Statements Next [counter] The keywords in the square brackets are optional. The arguments counter, start, end, and increment are all numeric. The loop is executed as many times as required for the counter to reach (or exceed) the end value. Execution of the For loop follows the following steps: 1. Sets counter equal to start. 2. Tests to see if counter is greater than end. If so, it exits the loop. If increment is negative the test is to see if counter is less than end. If it is it exits the loop. 3. Execute the statement in the block. 4. Increments counter by the amount specified with the increment argument. If the increment argument isn't specified, counter is incremented by 1. 5. Go to step 2. The following example scans all the elements of the numeric array data and calculates their average. For I = 0 to Ubound(Data) Total = Total + Data(I) Next I Debug.Print Total/Ubound(Data) The single most important thing to remember when working with ForNext loops is that the loop's counter is set at the beginning of the loop. Changing the value of the end variable in the loops body won't have any effect. For example the following loop will be executed 10 times not 100 times. EndValue = 10 For I = 1 to EndValue EndValue = 100 More statements Next I 53
WhileWend
The WhileWend loop executes a block of statements while a condition is True. The WhileWend loop has the following syntax: While condition Statement block Wend If condition is True, all statements are executed and when the Wend statement is reached, control is returned to the While statement which evaluates condition again. If condition is False, the program resumes with the statement following the Wend statement. The following example loop prompts the user for numeric data. The user can type a negative value to indicate that all values are entered. Number = 0 While Number => 0 Total = Total + Number Number = InputBox("Please enter another value") Wend
54
Instructions: STEP 1: Create a new script named EX03 STEP 2: Create a function called PriceCalc which accepts 2 numeric parameters, SalePrice and Discount, and returns a numeric value. STEP 3: Check that neither parameter is zero, if either are zero then return zero. STEP 4: Perform the calculation SalePrice (SalePrice * (Discount/100)) and return the result. STEP 5: Create a second function called Timeout which accepts a string parameter, outputs a Failed usercheck command with the parameter as the message and exits the script.
55
Example
56
Types of variables
Numeric Variables. Integer Long Single Double Currency Examples: Stores integer values in the range -32,768 to 32,767 Long integers in the range -2,147,483,648 to 2,147,483,647 Single precision floating point numbers in the range -3.402823e38 to -1.401298e-45, 0 can not be represented precisely. Double precision floating point numbers. Negative numbers in the range -1.79769313486232e308 to -4.94065645841247e-324 and positive numbers 4.94065645841247e-324 to 1.79769313486232e308. Fixed point number with 4 decimal digits in the range -922,337,203,685,477.5808 to 922,337,203,685,477.5807. Dim Count as Integer Dim DaysInCentury as Long Dim Length as Single Dim Area as Double
String Variables. The string data type store only text and are all declared the same way: Dim SomeText as String A string variable can theoretically hold almost 2gb of text. Examples: SomeText = "" rem sets Sometext to blank SomeText = "There are approx 12,000 words in this chapter" SomeText = "15,000"
57
Fixed Length Strings Strings vary in size to according to the values assigned to them. You can force a string to be a fixed length with a statement like the following; Dim SomeText As String * 1000 An assignment of less than 1000 characters will be padded with spaces, more than 1000 characters will be truncated. Boolean variables These have the value of -1 (For True) and 0 (For False) although any non-zero value will be considered false. Boolean variables are initialized to False. Dim Failure As Boolean Example: If Failure Then MsgBox "Test Failed"
Date Variables A variable declared as date can hold both data and time values. The declaration is: Dim Expiration As Date Examples: Expiration = "01/01/2003" Expiration = "13:03:05 AM" Expiration = "02/23/2002 3:03:05 AM" Expiration = #02/23/2001 10:03:05 PM#
Constants Constants do not change value once they have been declared and are faster in execution than variables. They are declared as follows: Const ConstantName [As Type] = value Examples: Const Pi As Double = 3.141592653589979 Const ExpDate = #31/12/2001#
58
Arrays
Declaring Arrays
Arrays must be declared with the Dim statement followed by the name of the array and the maximum number of elements it can hold. Dim Salary(15) As Long Dim Names(15) As String Note the type of the array is optional. Examples: Names(0) = "John Doe" Salary(0) = 34000 Names(1) = "Dave Smith" Salary(1) = 62000
Specifying Limits
By default an array has index values from 0 to the Dim statements upper bound, ie. in the above example the index went from 0 to 15 (16 entries). However it is possible to define the lower bound of an array explicitly as follows: Dim Names (1 to 16) as String Dim MyNumbers (10 to 20) as Long. Multidimensional Arrays When data is related as in the above example it can be more convenient to declare a multidimensional array. Dim NameSalary (15,15) NameSalary(0,0) = "John Doe" NameSalary(0,1) = 34000 NameSalary(1,0) = "Dave Smith" NameSalary(1,1) = 62000 Dim Matrix (9,9,9) This is a 3 dimensional array consisting of 1000 elements (10x10x10)
59
Collections
Arrays can only be accessed by a numeric index, if you want to use an Alphanumeric index value then we have to use collections. Collections can be useful for storing captured data where we use an alphanumeric value such as an id or name as an index. The collection is declared as follows: Dim Salaries As New Collection A collection object provides three methods and one property Add Method Remove Method Item method Count Property Adds items to the collections Deletes an item from the collection by index or key Returns an Item by index or key Returns the number of items in a collection.
Adding to a Collection
The Add method adds new items to a collection and has the following syntax: Collection.Add value, key, before, after To add a new element to a collection assign its value to the value argument and its key to the key argument. To place the item in a specific location in the array, specify one of the arguments before or after (but not both). To add the salary for John Doe to the Salary collection use the following statement: Salary.Add 34000,"John Doe" To add the salary for Dave Smith after John Doe use the statement: Salary.Add 62000,"Dave Smith",,"John Doe"
60
Counting a collection
The Count property returns the number of items in the collection. Number = Salary.Count You can also use the Count property to scan all the elements in a collection: For I = 1 to Salary.Count [process] Next I
Option Explicit
Using the "Option Explicit" statement is good programming practice. When the Option Explicit statement is at the start of a script, VBA generates a compile time error if it encounters a variable that has not been declared Option Explicit Sub Main() Dim Example As Double
61
Variable Scope
Variables declared in a script outside of any procedure or subroutine can be accessed by all the procedures within that script. If the variable is defined within a procedure then it can only be referenced within that procedure. Option Explicit Dim Var1 As Integer Sub Main() Dim Var2 As Double End Sub Sub Temp End Sub In the above example the variable Var1 is available to procedures Main and Temp, however Var2 is only available within Main. If it is required to make a variable available to more than one script then it should be defined in a shared module and instead of using the Dim statement the Public statement is used instead. Public Var1 As Integer
62
Instructions: STEP 1: Create a new script named EX04 STEP 2: Define a collection called "Temperatures". STEP 3: Write code to add the following 5 temperatures and cities with the cities as the key: 76 Atlanta 85 Los Angeles 97 Las Vegas 66 Seattle 70 New York STEP 4: Create a loop containing code that uses the "InputBox" function to request a city and "MsgBox" to display the temperature looked up by the city in the collection. Use the "On Error GoTo NotFound" command to go to a label (NotFound:) and exit the loop. STEP 6: Use MsgBox to display the count and average temperatue.
63
64
Input Box
65
Modules
Adding a Module
A module is a set of declarations, followed by procedures, that is designed to accomplish a particular task. The TestPartner module is equivalent to a Standard module in Visual Basic. In TestPartner, module assets are stored in the project in which they are created and have to be explicitly included in any test script that requires them. Select the option View -> Asset Browser on the menu bar.
66
Under Asset Types, right-click Module. Select New from the context menu.
TestPartner displays an empty code window. You can select Insert -> Procedure to add the template for a Public or Private subroutine, function, or property. You can write the code using Visual Basic syntax and TestPartner objects as you would any Visual Basic module.
Using A module
The following code is a simple timing module: Public TotalInterval as Double Dim T1 As Double Sub StartCounting() T1 = Time End Sub Sub StopCounting() TotalInterval = TotalInterval + Time - T1 End Sub Sub ResetTimer() TotalInterval = 0 End Sub Startcounting() starts the timer and the subroutine StopCounting() pauses the timer. Each time the timer is stopped, the TotaInterval variable is updated. A script to use this module to time a test would look as follows: '$TPInclude "TimerMod" Sub Main() StartCounting Rem code here StopCounting TestLog.Comment ("Time Taken =" & Hour(TotalInterval) & " Hours " & _ Minute(TotalInterval) & " minutes " & _ Second(TotalInterval) & " seconds.") End Sub
67
Shared Modules
Adding a Shared Module
As in Visual Basic, a TestPartner Shared Module is a set of declarations, followed by procedures, that is designed to accomplish a particular task. In TestPartner, a shared Module is stored in a designated project and is automatically visible to all assets in that project. To use shared modules in other projects, you must explicitly include them in any test script that requires them. Select the option View -> Asset Browser on the menu bar. Under Asset Types, right-click Shared Module. Select New Shared Module from the context menu.
TestPartner displays an empty code window. You can select Insert | Procedure to add the template for a Public or Private subroutine, function, or property. You can write code using Visual Basic syntax and TestPartner objects as you would any Visual Basic module.
68
Class Modules
Adding a Class Module
A class module is the definition of a class, including its properties and methods. You can use class modules when you need to explicitly control scope of visibility. The TestPartner class module is equivalent to class modules in Visual Basic. For more information, see "classes" and "Class Module" in the Visual Basic help. Class module assets are not automatically visible to other assets in a project. Select the option View -> Asset Browser on the menu bar. Under Asset Types, right-click Class Module. Select New Class Module from the context menu.
TestPartner displays an empty code window. You can select Insert | Procedure to add the template for a Public or Private subroutine, function, or property. You can write the module using Visual Basic syntax and TestPartner objects as you would any Visual Basic module.
69
There is no longer a public variable, the variable TotaInterval can only be accessed through the ElapsedTime() procedure. This is a special type of procedure called Property Get. The value of the TotalInterval variable can only be accessed through the ElapsedTime procedure. Its code reads the value of the TotalInterval local variable and assigns it to the ElapsedTime() procedure. This is the value that is returned to the calling script. This example does not need to set a variable in the class module but if it was needed then you would have a Property Let procedure, the opposite of the Property Get. You can also have Private procedures which can be called from within the module but can not be accessed from outside the module. The methods of the Class Module are identical to the methods of the Module. Adding a method to a Class is as simple as declaring a Public function or subroutine in that class module. The script to use the class module is as follows: '$TPInclude "ClassTimerMod" Sub Main() Dim Etime As Double Dim TMR As New ClassTimerMod TMR.StartCounting TestLog.Comment ("Count started") Rem code here Pause 5 TMR.StopCounting Etime = TMR.ElapsedTime TestLog.Comment ("Time Taken =" & Hour(Etime) & " Hours " & _ Minute(Etime) & " minutes " & _ Second(Etime) & " seconds.") End Sub
70
Instructions: STEP 1: Create a Class Module using the timer code described in this chapter. STEP 2: Copy script EX02 and save it as EX05 STEP 3: Modify EX05 to make the Timer Class module available STEP 4: Use the timer class module to time how long EX05 takes to run and how long each of the child scripts take to run. STEP 5: Write all 4 timing values to the script log. Examples The Class Module ClassTimerMod
71
Script EX05 Option Explicit '$TPInclude "ClassTimerMod" Sub Main() Dim EX05Time, SignonTime, ClearDBTime, ShutdownTime As Double Dim TMR1 As New ClassTimerMod Dim TMR2 As New ClassTimerMod TMR1.ResetTimer TMR1.StartCounting TMR2.ResetTimer TMR2.StartCounting Run ("Signon") TMR2.StopCounting SignonTime = TMR2.ElapsedTime TMR2.ResetTimer TMR2.StartCounting Run ("ClearDataBase") TMR2.StopCounting ClearDBTime = TMR2.ElapsedTime TMR2.ResetTimer TMR2.StartCounting Run ("Shutdown") TMR2.StopCounting ShutdownTime = TMR2.ElapsedTime TMR1.StopCounting EX05Time = TMR1.ElapsedTime TestLog.Comment ("EX05 Time: " & Minute(EX05Time) & " minutes " _ & Second(EX05Time) & " seconds.") TestLog.Comment ("Signon Time: " & Minute(SignonTime) & " minutes " _ & Second(SignonTime) & " seconds.") TestLog.Comment ("Clear DB Time: " & Minute(ClearDBTime) & " minutes " _ & Second(ClearDBTime) & " seconds.") TestLog.Comment ("Shutdown Time: " & Minute(ShutdownTime) & " minutes"_ & Second(ShutdownTime) & " seconds.") End Sub Extract from Log of EX05
72
73
Recording clicking on the second item in the listbox and then clicking on the Open Dialog button results in the following code: Window("This Is A Delphi Program Window").Attach GUIObject("ClassName=TListBox Caption=''").Attach GUIObject.TextSelect "Item 2" GUIObject("ClassName=TButton Caption='Open Dialog'").Attach GUIObject.Click 17, 20
Because this is a Delphi program the listbox class is actually TlistBox rather than ListBox and the button has a class of TButton instead of Button. TestPartner has recorded the controls as GuiObjects and recorded an attach to the objects and then an action on each object, a textselect in the case of the list and a mouseclick in the case of the button. However as it is quite clear that these controls are a listbox and a button we can register them as that in the Alias Map. Having done this if we record the above script again the following script is generated: Window("This Is A Delphi Program Window").Attach ListBox("Parent.Caption=Panel1").Select "Item 2" Button("Caption='Open Dialog'").Click This generates a script that is much more sensible, easier to read and interpret, and faster to execute. TestPartner attaches to the Window (This is a Delphi Program) selects a listbox item and clicks the Open Dialog button . All the previous references to GUI objects are gone and textselects and mouseclicks have been replaced by commands which represent the object they are operating on.
74
It is not necessary to register every non-standard control as a standard control. You should only need to register one example of each non-standard type. The Alias Map will then apply the same mapping to all other controls of the same class.
3. Click on the Create button (just above Class Name) and the Object Selection window appears.
75
4. Click the Identify button and place the mouse pointer over the object to be registered. The object must be highlighted (surrounded by a shadow border) to be registered in the Alias map. Note: If the object is not highlighted then it is not a true control. It is a bitmap (picture) with the appearance of a control and cannot be registered. Use Image mapping rather than alias mapping to register this type of control. 5. Click once with the left mouse button; the object's details are automatically entered into the identify window. 6. Click the OK button on the object selection window. The Add Class Alias dialog box displays:
76
7. Type a Description of the control and select a standard control alias from the Alias name drop-down list. 8. Click OK to complete the registration. 9. The entry is made into the Alias Map window, to add another entry click on the Create button again. If there are no more objects to register then close the Alias Map (Winclose button or menu entry file->close). You should test the registration by learning your trial script again. In some circumstances, alias mapping does not produce the results you might expect. This usually happens when the internal behavior of the non-standard control does not resemble the type of control it is mimicking.
77
3. Change the Class name, Description, and Alias name entries as required. Note: Modifying Alias Map entries will cause the scripts that use the old definition to fail.
78
Instructions: STEP 1: Switch off the Text Select option for recording. STEP 2: Record Loading the delphi sample application supplied by the instructor. STEP 3: Record clicking on the Open Dialog Button, Click on the OK button displayed in the Sample Dialog window, Click on the Close App button. STEP 4: Set up an Alias for the buttons. STEP 5: Record the script again and look at the differences.
79
Examples. Script before using Alias's. Sub Main() Window("Window").Attach Button("Caption=Start").Click Window.PopupMenuSelect "Run..." Window("Run Window").Attach ComboBox("Label='&Open:'").SetText _ "C:\Program Files\Compuware\TestPartner\DelphiSample.exe" Button("Caption=OK").Click Window("This Is A Delphi Program Window").Attach Window.Size 870, 691 Window.Move 77, 38 Window("This Is A Delphi Program Window").Attach Window.Size 870, 691 Window.Move 77, 38 GUIObject("ClassName=TButton Caption='Open Dialog'").Click 68, 22 Window("Sample Dialog 1 Window").Attach GUIObject("ClassName=TButton Caption=OK").Click 152, 44 Window("This Is A Delphi Program Window").Attach GUIObject("ClassName=TButton Caption='Close App'").Click 27, 19 End Sub Setting the Alias
80
The Final script with the Alias. Sub Main() Window("Window").Attach Button("Caption=Start").Click Window.PopupMenuSelect "Run..." Window("Run Window").Attach ComboBox("Label='&Open:'").SetText _ "C:\Program Files\Compuware\TestPartner\DelphiSample.exe" Button("Caption=OK").Click Window("This Is A Delphi Program Window").Attach Window.Size 870, 691 Window.Move 77, 38 Window("This Is A Delphi Program Window").Attach Button("Caption='Open Dialog'").Click Window("Sample Dialog 1 Window").Attach Button("Caption=OK").Click Window("This Is A Delphi Program Window").Attach Button("Caption='Close App'").Click End Sub
81
82
83
Then within the Options window, in the Record section ensure that the Bitmap selects is set to Yes.
The following is a recording against a calculator (below) where what appear to be buttons are actually just pictures within a window. The recording is done without the bitmap select option, and is a recording of 4 * 5 = .
84
The resulting script is: Sub Main() Window("Calculator Window").Attach Window.Click 79, 131 Window.Click 195, 135 Window.Click 120, 134 Window.Click 237, 199 End Sub While the above code is valid, and will always work it is not possible to understand which buttons have been clicked. To make the script clearer, we can use the bitmap select option. This, if on will automatically generate bitmaps according to the window name and position on the image that is clicked. However even this is not very satisfactory as in the above case the script would be: Window("Calculator Window").Attach Window.BitmapSelect "Calculator" Window.BitmapSelect "Calculator1" Window.BitmapSelect "Calculator2" Window.BitmapSelect "Calculator3" Not only can we still not understand from the script what keys are being pressed, but if we go to the object map in testpartner:
85
Then we double click on an entry (Calculator1) in the window to display the details and select the Preview Image tab. Unfortunately we discover that we must have clicked on the corner of the button and the image learnt still does not tell us which key this is.
The solution to all the above problems is to learn all the required images first. We learn images by ensuring we are in the object map section of the asset browser, right click on Object Map in the left pane, select New Map Entry and then Image:
86
This takes us to a screen where we can name what we are going to capture (Calculator_Button_No4) and then click on the Capture button to go and draw a box around the key whose image we want to store.
If we then check the preview image tab of the Image Map window we will find we have a good recording of the image.
87
And we can then save and close the image details. By repeating the above process for every image we require to capture we can ensure that we have an understandable script as follows: Window("Calculator Window").Attach Window.BitmapSelect "Calculator_Button_No4" Window.BitmapSelect "Calculator_Button_Multiply" Window.BitmapSelect "Calculator_Button_No5" Window.BitmapSelect "Calculator_Button_Equals" The basic rule of using bitmap images is that if they are required it is best to learn them first to ensure good naming conventions and sensible stored bitmap images.
88
TextSelects
The TextSelect option allows the selection of text when this text may not be on a recogniseable control. The TextSelect option generates simpler code which does not require storing information in the database. The text select option is selected in the same way as bitmap selects above.
Now when we record our Calculator example we get the following script: Sub Main() Window("Calculator Window").Attach Window.TextSelect "4" Window.TextSelect "*" Window.TextSelect "5" Window.TextSelect "=" End Sub
89
You must be careful to click exactly on the character, if you miss the character then the bitmap option will be used instead (assuming bitmap selects are still switched on), however Text Selects always take priority over Bitmap Selects. Also with Text Selects care must be taken that the same text does not exist elsewhere in the window as the first occurrence of this text will be the one selected when playing back the script.
90
Instructions: STEP 1: Switch on Bitmap selects and Text Selects STEP 2: In the Signon Script add a recording of clicking on the ? on the toolbar and then closing the information window. STEP 3: Learn the bitmap image for the ? icon and replace the recorded "HTMLBrowser.Click 184, 71" with a Window.BitmapSelect command for the for the image. STEP 4: Examine the Shutdown script and where the menu was used to logoff replace the Clicks with TextSelects.
Examples:
Mouseclick on the ? icon. Window("Microsoft Internet Explorer").Attach HTMLBrowser("Caption='QADemo - Main'").Attach HTMLBrowser.Click 184, 71 Window("Microsoft Internet Explorer").Attach Window.Close
91
Code with the BitmapSelect. Window("Microsoft Internet Explorer").Attach HTMLBrowser("Caption='QADemo - Main'").Attach Window.BitmapSelect "ToolBar_Question_Mark" Window("Microsoft Internet Explorer").Attach Window.Close Shutdown code with click commands Sub Main() Window("Microsoft Internet Explorer").Attach HTMLBrowser("Caption='QADemo - Main'").Attach HTMLTD("ID=td_1").Click 16, 9 HTMLTD("ID=td_1_3").Click 21, 8 Window.Attach Window.MenuSelect "File~Close" End Sub Shutdown script with TextSelects Sub Main() Window("Microsoft Internet Explorer").Attach HTMLBrowser("Caption='QADemo - Main'").Attach HTMLBrowser("Caption='QADemo - Main'").TextSelect ("File") HTMLBrowser("Caption='QADemo - Main'").TextSelect ("Logoff") Window.Attach Window.MenuSelect "File~Close" End Sub
92
93
94
Close (#myFile) The final script to use the above code would thus look similar to the following: Sub Main() Dim myFile As Integer Dim TextLine As String Dim SplitArray() As String myFile = FreeFile() Open "C:\testdata\customer.csv" For Input As #myFile ' start the loop Do While Not EOF(myFile) ' input a record and split into fields Line Input #myFile, TextLine SplitArray = Split(TextLine, ",") Window("New Customer Details Window").Attach EditBox("Label='&Name :'").SetText SplitArray(0) EditBox("Label='&LastName :'").SetText SplitArray(1) EditBox("Label='&Address :'").SetText SplitArray(2) Button("Caption=OK").Click Loop ' End of the while not eof loop
Close #myFile
95
We need variable definitions for the Excel application, workbook and worksheet as follows: Dim apExcel As Excel.Application Dim wbCustomer As Excel.Workbook Dim shAddress As Excel.Worksheet Then to start the excel interface and open a workbook and worksheet we need the following code: Set apExcel = New Excel.Application Set wbCustomer = apExcel.Workbooks.Open("C:\testdata\customer.xls") Set shAddress = wbCustomer.Worksheets("customer")
96
Obviously the filename and worksheet name should match your spreadsheet and not be exactly as above. The rows and columns within the spreadsheet are accessed with the "shAddress.Cells.Item(r, c)" statement. "r" is the row, and the first row is 1, "c" is the column and the first column is 1. Thus using the data given earlier in this chapter, if it was in an excel spreadsheet, "shAddress.Cells.Item(1, 2)" would return "Joe" and "shAddress.Cells.Item(2, 1)" would return "Smith". The final script to duplicate what is being done in the CSV file example above would be similar to the following: Sub Main() Dim apExcel As Excel.Application Dim wbCustomer As Excel.Workbook Dim shAddress As Excel.Worksheet Dim i, j As Integer Set apExcel = New Excel.Application Set wbCustomer = apExcel.Workbooks.Open("C:\testdata\customer.xls") Set shAddress = wbCustomer.Worksheets("customer") For i = 1 To 3 Step 1 Window("New Customer Details Window").Attach EditBox("Label='&Name :'").SetText shAddress.Cells.Item(i,1) EditBox("Label='&LastName :'").SetText shAddress.Cells.Item(i,2) EditBox("Label='&Address :'").SetText shAddress.Cells.Item(i,3) Button("Caption=OK").Click Next ' End of for loop End Sub Note that we now need to know the number of rows in the spreadsheet, this could be overcome by putting a special terminator record in the spreadsheet and testing for it.
97
FieldCount = FieldCount + 1 End If Next OpenData = myFile End Function Public Function ReadNextDataRecord() As Boolean '***************************************************************** '* Read the next data record and store the data in a collection using '* the fieldnames obtained at file open for reference '***************************************************************** Dim I As Integer If Not EOF(myFile) Then '-----------------------------------------' 1st remove existing items from collection '-----------------------------------------For I = Data.Count To 1 Step -1 Data.Remove (I) Next '-----------------------------------------------' read the next line and split on field seperator '-----------------------------------------------Line Input #myFile, TextLine SplitArray = Split(TextLine, ",") '----------------------------------------------------------' Store in the data collection using the fieldnames as a key '----------------------------------------------------------For I = 0 To FieldCount - 1 Data.Add SplitArray(I), FieldNames(I) Next ReadNextDataRecord = True Else ReadNextDataRecord = False End If End Function '************************************************* '* Return the data item at the named key position '************************************************* Property Get DataItem(ItemName As String) As String DataItem = Data.Item(ItemName) End Property '************************************************* '* Close the file '*************************************************
99
100
Using the above code is very straightforward, but to demonstrate how we first need a simple test data file: Reference,Make,Color Car0012,Ford,Green Car0023,Pontiac,Blue Car0045,Chevrolet,Black The above file is a comma separated file with 3 fields in each of 3 data records. The header record provides us with field names Reference, Make, and Color. Before we can access the functions within the Class Module from our script we will have to include the class module and define a new instance of the TestDataFunctions object: '$TPInclude "TestDataFunctions" Sub Main() Dim TD As New TestDataFunctions we will call our test data object TD
Once this is done we can access the functions within the class module: TD.OpenData ("C:\Temp\TestFile.csv") Opens the data file for us and reads in the heading details. TD.ReadNextDataRecord Reads the next data record and returns a value of True if there is a data record and False if there is not a record. TD.DataItem("Reference") Returns the data item for Reference in the current record (Car0012 in the first record). TD.CloseData This closes the data file. 101
A small script to read the above data and display each record could look like the following: '$TPInclude "TestDataFunctions" Sub Main() Dim TD As New TestDataFunctions TD.OpenData ("C:\Temp\TestFile.csv") Do While TD.ReadNextDataRecord = True MsgBox (TD.DataItem("Reference") & " " & TD.DataItem("Make") _ & & TD.DataItem("Color")) Loop TD.CloseData End Sub
102
Instructions: STEP 1: Create a class module called TestDataFunctions as described in the chapter above. STEP 2: Copy Script EX05 and save as Script EX08. STEP 3: Place an end statement between the Run ClearDataBase and the Run Shutdown statements in the script. Execute the script, when the End statement is encountered the application will be left at the correct position to start recording a script to enter data. STEP 4: Create a new script called AddCars. Record the following actions on QADemo Web: Select File->Main Options Select Add Car in the list box and click on OK Type the following information into the Add Car Window: 1. Ref: Car 1 2. Make: Ford 3. Engine Size: 3000 4. Year: 1999 5. Doors: 4 6. Color: Blue 7. Sale Price; 4000 8. Dealer Discount: 15 9. Quantity: 1 Select all 6 Extras (checkboxes) Click the Add button Click the Cancel button (On the Add Car Window) Click the Cancel button (On the New Window) The application should be back at the point the script started. 103
STEP 5: Add a Run AddCars to script EX08 in place of the End statement inserted in step 3. Run script EX08 to ensure it is functioning correctly. STEP 6: Create the following comma separated test data file (cars.csv) using notepad or excel, ensure the first row contains the header information.
STEP 7: Modify the Add Cars Script to open the test data file and read the first line of data. '$TPInclude "TestDataFunctions" TD.OpenData ("C:\Temp\cars.csv") TD.ReadNextDataRecord STEP 8: Modify the HTMLEditBox commands to use the DataItem Function to return the required value from the file. HTMLEditBox("Add Car Window Reference Edit").SetText "Car 1" Becomes HTMLEditBox("Add Car Window Reference Edit").SetText TD.DataItem("Ref") STEP 9: Modify the script to use an if statement on the checkbox values from the test data file to decide whether to click on the checkbox or not. If TD.DataItem("Radio") = "on" Then HTMLCheckBox("Name=chkRadio").Click End If STEP 10: Run the script and ensure it reads the first line of data and enters it into the application.
104
STEP 11: Build a while loop into the AddCars script to read the entire test data file: TD.OpenData ("C:\Temp\cars.csv") While TD.ReadNextDataRecord = True STEP 12: Run the script to ensure it is functioning correctly.
105
Examples: QADemo Web application at required point to record a script to input data.
106
Initial AddCars Script Sub Main() Dim oe As TOnError Set oe = OnError("QADemoErrorFunction") Window("Microsoft Internet Explorer").Attach HTMLBrowser("Caption='QADemo - Main'").Attach HTMLTD("ID=td_1").Click 16, 4 HTMLTD("ID=td_1_1").Click 30, 7 HTMLBrowser("Caption='QADemo - New'").Attach HTMLListBox("Name=lstNew").Select "Add Car" HTMLButton("OK HTMLButton").Click HTMLBrowser("Caption='QADemo - Add Car'").Attach HTMLEditBox("Add Car Window Reference Edit").Click 9, 10 HTMLEditBox("Add Car Window Reference Edit").SetText "Car 1" HTMLEditBox("Add Car Window Make Edit").SetText "Ford" HTMLEditBox("Add Car Window Engine Size Edit").SetText "3000" HTMLEditBox("Add Car Window Year Edit").SetText "1999" HTMLEditBox("Add Car Window Doors Edit").SetText "4" HTMLEditBox("Add Car Window Color Edit").SetText "Blue" HTMLEditBox("Add Car Window Cost Edit").SetText "4000" HTMLEditBox("Add Car Window DealerDiscount Edit").SetText "15" HTMLEditBox("Add Car Window Quantity Edit").SetText "1" HTMLCheckBox("Name=chkRadio").Click HTMLCheckBox("Name=chk4wd").Click HTMLCheckBox("Name=chkSunRoof").Click HTMLCheckBox("Name=chkLeather").Click HTMLCheckBox("Name=chkAirCond").Click HTMLCheckBox("Name=chkMetallic").Click HTMLButton("Add HTMLButton").Click HTMLBrowser("Caption='QADemo - Add Car'").Attach HTMLButton("Cancel HTMLButton").Click HTMLBrowser("Caption='QADemo - New'").Attach HTMLButton("Cancel HTMLButton").Click Window.Attach End Sub
107
Script Modified to read a line of test data file. TD.OpenData ("C:\Temp\cars.csv") TD.ReadNextDataRecord HTMLBrowser("Caption='QADemo - Add Car'").Attach HTMLEditBox("Add Car Window Reference Edit").Click 9, 10 HTMLEditBox("Add Car Window Reference Edit").SetText TD.DataItem("Ref") HTMLEditBox("Add Car Window Make Edit").SetText TD.DataItem("Make") HTMLEditBox("Add Car Window Engine Size Edit").SetText TD.DataItem("Size") HTMLEditBox("Add Car Window Year Edit").SetText TD.DataItem("Year") HTMLEditBox("Add Car Window Doors Edit").SetText TD.DataItem("Doors") HTMLEditBox("Add Car Window Color Edit").SetText TD.DataItem("Color") HTMLEditBox("Add Car Window Cost Edit").SetText TD.DataItem("Price") HTMLEditBox("Add Car Window DealerDiscount Edit").SetText TD.DataItem("Discount") HTMLEditBox("Add Car Window Quantity Edit").SetText TD.DataItem("Quantity") If TD.DataItem("Radio") = "on" Then HTMLCheckBox("Name=chkRadio").Click End If If TD.DataItem("4wd") = "on" Then HTMLCheckBox("Name=chk4wd").Click End If If TD.DataItem("SunRoof") = "on" Then HTMLCheckBox("Name=chkSunRoof").Click End If If TD.DataItem("Leather") = "on" Then HTMLCheckBox("Name=chkLeather").Click End If If TD.DataItem("AirCond") = "on" Then HTMLCheckBox("Name=chkAirCond").Click End If If TD.DataItem("Metalic") = "on" Then HTMLCheckBox("Name=chkMetallic").Click End If HTMLButton("Add HTMLButton").Click
108
Script Changes for While loop TD.OpenData ("C:\Temp\cars.csv") While TD.ReadNextDataRecord = True HTMLBrowser("Caption='QADemo - Add Car'").Attach HTMLEditBox("Add Car Window Reference Edit").SetText TD.DataItem("Ref") HTMLEditBox("Add Car Window Make Edit").SetText TD.DataItem("Make") Main code goes here HTMLButton("Add HTMLButton").Click Wend TD.CloseData
109
Wait Events
The wait command below may have been inserted into your script to wait for a database update to complete before continuing: If Wait(30, "Add Car to DB", tpWaitSeconds) = True Then TestLog.Comment "Event Add Car to DB triggered" Else TestLog.Comment "Event Add Car to DB did not trigger, timeout of 30 _ seconds has been exceeded." End If This could have been inserted using ALT-F7 the shortcut while recording or using the insert menu option while in a script:
110
Whenever Events
If we need to be able to handle another event at the same time we must use a Whenever event command, and this must be defined prior to the wait command to ensure it can be triggered while waiting for the wait event. This could have also been done via an ALT-F7 while recording or it can also be done through the Insert menu. As a whenever event is unlikely to occur at the correct time while recording it is more likely the event will have already been learnt and will now be inserted as follows:
111
With the cursor positioned at the start of the script but after Sub Main the insert menu option is used to insert an event.
Select the event that it is required to use and click on the Insert button.
112
Select the Whenever radio button and Click on the OK button. Sub Main() Whenever (Duplicate Car) If Wait(30, "Add Car to DB", tpWaitSeconds) = True Then TestLog.Comment "Event Add Car to DB triggered" Else TestLog.Comment "Event Add Car to DB did not trigger, timeout of 30 _ & seconds has been exceeded." End If ---------------------------------------------------------------------------------------------Private Sub Script_Whenever(ByVal TheEvent As TPEvents.TEventGroup) End Sub The result, as shown above, is a Whenever event command inserted where we had the cursor positioned, and a subroutine called Script_Whenever inserted at the end of our script to handle the event. Regardless of the number of Whenever commands, there is only one subroutine to handle them in a script. So we must add the following code to determine which Whenever event has just triggered: Private Sub Script_Whenever(ByVal TheEvent As TPEvents.TEventGroup) Select Case TheEvent.Name Case "Duplicate Car" Put code here to handle the error prior to returning to the script ResumeScript Case Else MsgBox "Unknown Event " & TheEvent.Name End End Select End Sub
113
The above select statement switches on the return value from the Object method TheEvent.Name, which returns the name of the whenever event that has just been triggered. Code must be added to handle the event here, if this event occurred while waiting on another event, such as the wait in the example above, then you may need to execute code to ensure the wait event works without error on exiting from the whenever code. The command ResumeScript returns control to the script at the point the whenever event was triggered.
114
Instructions: STEP 1: Copy script EX08 to script EX09, within the script change the Run AddCars to Run AddCarsEvents. Copy script AddCars to AddCarsEvents. STEP 2: Place an End instruction after adding the first car details in AddCarsEvents and run script EX09. This should position the application (QADemo Web) with a blank add cars window. Remove the End from AddCarsEvents. STEP 3: With the cursor positioned after the HTMLButton("Add HTMLButton").Click in script AddCarsEvents add a wait screen event which checks that the Ref: field is blank. If the event works, log that the data was added to the database, if not log that the data addition failed. STEP 4: Add the same car details to QADemo Web twice to create a duplicate car error window. At the beginning of the AddCarsEvents script insert a Whenever Screen event to look for the Duplicate Record text. STEP 5: In the Script_Whenever subroutine added to the bottom of the AddCarsEvents script, add code to determine which error has occurred, output a suitable Usercheck command, and add (record) code to recover back to the add car window. STEP 6: Add the following two lines of data to the cars.csv data file.
Ford Taurus Chrysler Sebring 6 cyl 6 cyl 1997 1997 4 Green 2 Black 17500 18995 20 15 10 on 10 on off on on on off on on on off on DUP DUP
STEP 7: Run Script EX09 and ensure everything is working correctly (2 duplicates). STEP 8: Add an extra column to the data called Results, in this column put the words ADD or DUP according to the expected results. STEP 10: Modify the error reporting so that if the result is as expected the usercheck gives a pass and not a fail.
115
116
117
118
Identify icon
This is achieved by the use of the Object Selection screen which is accessed via the identify icon.
The recording must be stopped and the cursor positioned with the script at the point you wish to capture. If you are adding captures to an existing script you can reach this point by inserting a stop command in the script and running the test script(s) to this point which ensures the script and the application are synchronized. In the following example of inputting data to the QADemo Car Database we wish to capture the Dealer Discount value to check if this has been calculated correctly.
119
120
121
We now identify the field that we wish to capture. This is achieved by clicking on the Identify button on the Object Selection Screen. This takes us back to the application with a cursor that we should position over the field we wish to capture and then click the mouse button. Note that Testpartner displays the field type as the cursor is positioned over it.
122
Control is returned to the Object Selection Screen once you have clicked on the required field in the application. You can check in the right hand pane that the field details match what you intended to click on (mistakes do happen).
123
In our case we can tell that the type is an HTMLEditBox and that its name is txtDealerPrice, which is the field we are interested in. We then click on the OK button and the field details are pasted into the script: HTMLEditBox("Add Car Window Quantity Edit").SetText "2" HTMLCheckBox("Name=chkRadio").Click HTMLCheckBox("Name=chkAirCond").Click HTMLEditBox ("Application=IEXPLORE.EXE Name=txtDealerPrice") HTMLButton("Add HTMLButton").Click We should add a variable to receive the captured value, not forgetting to define this variable (as a string) earlier in the script. Dim DealerPrice as String
HTMLEditBox("Add Car Window Quantity Edit").SetText "2" HTMLCheckBox("Name=chkRadio").Click HTMLCheckBox("Name=chkAirCond").Click DealerPrice = HTMLEditBox ("Application=IEXPLORE.EXE Name=txtDealerPrice") HTMLButton("Add HTMLButton").Click
CaptureText Method
By then typing a period at the end of the Dealer Price line we are presented with a list of methods available on this object, one of these is CaptureText, which we select.
124
Now that the contents of the Dealer Price edit field have been captured, they may be processed as required within the script.
125
Instructions: STEP 1: Copy script EX09 to script EX10, within the script change the Run AddCarsEvents to Run AddCarsCapture. Copy script AddCarsEvents to AddCarsCapture STEP 2: In the AddCarsCapture script place an End statement prior to the HTMLButton("Add HTMLButton").Click statement and run script EX10. This should place application QADemo Web at the correct place to capture fields from the Add Cars window. STEP 3: Replace the End statement with Capture commands for the following fields: Sale Price, Dealer Discount, Dealer Price. STEP 4: The dealer price should be equal to: SalePrice (SalePrice * Discount / 100) Add a calculation to check this and report the results with an appropriate usercheck.
126
127
While this is fine during development of the script, it is less desirable when executing the script in the final test environment. It requires someone to be present to take action and it stops any further tests running on that machine until that action is taken. It is possible to detect these errors within your script and take whatever action is possible to either recover or, at a minimum, to log the error details and terminate the script to enable another to continue.
128
129
Error Properties
There are several error properties which can be used to obtain the details of the error. The syntax to obtain error properties is as follows: variable = object.Error.{property} "Variable" is a reference to the Testpartner TError object. "Object" is Testpartner and again is usually ommitted. "Property" is one of the properties of the TError object that describes the nature of the error and where it occurred. Error.SourceFile returns the name of the script the error occurred in. Error.SourceLine returns the numeric line number in the script the error occurred on. Error.Message returns the error message. Error.Function returns the command in error. To output the error details to the script log, the following code could be used: TestLog.Comment "error in script " & Error.SourceFile TestLog.Comment "error on line " & Cstr (Error.SourceLine) TestLog.Comment "error in function " & Error.Function TestLog.Comment "error message " & Error.Message Note. The Cstr function is used to convert the numeric line number to a string.
Thus the last line of the error handling function might be: MyErrorFunction = tpResumeNext
130
Which will exit back to the command after the one which caused the error.
131
Instructions: STEP 1: Open a new Shared Module called ErrorHandling. STEP 2: Create a function called QADemoErrorFunction. STEP 4: Within the Function insert a log comment that a fatal error has occurred and add log comments for all the details available. Add an End statement to terminate execution. STEP 5: Create another function called AppStop. Use a window event to check if the browser exists and record closing the IE Browser in the function if it does. STEP 6: Add a call to AppStop in QADemoErrorFunction before the End. STEP 7: Via the options menu change the default script to always contain code to use QADemoErrorFunction. STEP 8: Copy EX10 script to EX11 and add the code to enable error handling via QADemoErrorFunction. STEP 9: Add a window.attach to EX11 at the end of the script to force an error. Run the script to ensure error handling works. Remove the window.attach from the script.
132
Examples: Error Handling Module Function QADemoErrorFunction() As tpOnErrorType TestLog.Comment "Fatal Error in QADemo Web Application" TestLog.Comment "error in script " & Error.SourceFile TestLog.Comment "error on line " & CStr(Error.SourceLine) TestLog.Comment "error in function " & Error.Function TestLog.Comment "error message " & Error.Message If AppStop() Then TestLog.Comment "Application Terminated" End If End End Function Function AppStop() As Boolean If Wait(3, "IE Explorer Present", tpWaitSeconds) = True Then Window("Microsoft Internet Explorer").Attach Window.MenuSelect "File~Close" AppStop = True Else TestLog.Comment "IE Explorer not present." AppStop = False End If End Function
133
Default Script
Script EX11 Option Explicit '$TPInclude "ClassTimerMod" Sub Main() Dim oe As TOnError Set oe = OnError("ErrorHandling.QADemoErrorFunction") Dim EX05Time, SignonTime, ClearDBTime, ShutdownTime As Double Main script code goes here
TestLog.Comment ("Shutdown Time: " & Minute(ShutdownTime) & " minutes " _
134
135
MsgBox
This displays a dialog box containing a message, buttons, and optional icon to the user. The action taken by the user is returned by the function in the form of an integer value. The syntax of the command is as follows: MsgBox (Prompt [, buttons][, title]) Prompt: A required parameter of data type string, this is the message to display. Buttons: An optional parameter of data type numeric, the default value is vbOKOnly (value 0) which displays an OK button. This value can be the sum of values for the buttons displayed, the icon required, and the default button. Button Types Constant vbOkOnly vbOKCancel vbAbortRetryIgnore vbYesNoCancel vbYesNo vbRetryCancel Value 0 1 2 3 4 5 Buttons to Display OK Only OK and Cancel Abort, Retry, and Ignore Yes, No, and Cancel Yes and No Retry and Cancel Icon to Display Critical Message Warning Query Warning Message Information Message Default Button First Button Second Button Third Button Fourth Button
Icon Display Constants Constant Value vbCritical 16 vbQuestion 32 vbExclamation 48 vbInformation 64 Default Button Constants Constant Value vbDefaultButton1 0 vbDefaultButton2 256 vbDefaultButton3 512 vbDefaultButton4 768
136
Value 1 2 3 4 5 6 7
Title: An optional title (string) for the message box. Note! Additional helpfile parameters are beyond the scope of this manual. Example: reply = MsgBox("My Prompt", vbAbortRetryIgnore + vbDefaultButton2, "My Title") This outputs the following message box:
The default Retry button will return a value of 4 The following MsgBox: reply = MsgBox("My Prompt", vbExclamation + vbDefaultButton1 + vbYesNo, "My Title") Gives:
137
The message box can be useful to display values without having to use the VBA debugging system, and can also be useful for controlling a demonstration of the script as it stops processing until a button is pressed.
InputBox
This function displays a dialog box containing a lable, which prompts the user about the data you expect them to input, a text box for entering the data, an OK button, aCancel button, and optionally a Help button. When the user clicks OK, the function returns the contents of the text box. The syntax of the command is as follows: InputBox (Prompt [,title] [,default] [,xpos] [,ypos]) Prompt: A required string which is the message in the box. Title: An optional string for the titlebar.
Default: An optional string to be displayed in the text box on loading, provides a default return value. Xpos: The optional position measured from the left of the screen. Ypos: The optional position measured from the top of the screen. Examples: reply = InputBox("MyPrompt", "The Title", "Default value")
If default value is not changed and OK is clicked then Default value is returned. If the Cancel button is clicked then nothing is returned. This can be used as a simple method of inputting data and also to display and give the option to change values within a script.
138
Debugging Scripts
The debugging options available through the debug menu enable you to set breakpoints at various commands, step through your script, and examine variables.
A breakpoint may be set by clicking in the gray column next to the line the breakpoint is required to be on. When the script is run it will stop execution on the breakpoint line, contents of a variable can be examined by placing the cursor over the variable.
139
A variable may be added to the watch window by double clicking on it or via the debug menu add watch. Then the variable can be examined as you step through the script with Step Into, Step Over, Step Out, and Run to Cursor commands. A section of script can be skipped by placing the cursor on the line you wish to continue exucution and taking the debug option Set Next Statement. The breakpoints can be toggled on a specific line using the Toggle Breakpoint menu option, and all breakpoints can be removed by the Clear All Breakpoints menu option.
User Forms
It is possible within testpartner to create your own forms. A form provides fields where you can enter additional information or read additional information. Forms can also provide formatted output in ways that a message box cant. Forms can be activated from within your Testpartner script. Within Testpartner to create a form, in the Asset browser right click on UserForm and select New UserForm The resulting display shows a blank userform and a toolbox with the basic controls that are available. 140
The tools in the toolbox from left to right are: Top Row: Select Objects Label TextBox ComboBox ListBox CheckBox RadioButton ToggleButton Bottom Row: Frame CommandButton TabStrip MultiPage Scrollbar SpinButton Image RefEdit
141
We can add controls to the window by clicking on the required control and then Clicking on the required position within the window. The following diagram shows a simple input window with a Heading (using a label), two Labels, two Editboxes and two Buttons.
142
We can give the labels, fields, and buttons meaningful names and contents by invoking the properties window from the view menu:
143
144
By changing the name and the caption we can give our fields sensible names and meaningful display values, we can also change the font type and size used. The size of the display can be adjusted by clicking on the small boxes and dragging the edge of the field to the required size.
145
On the following form the label Names and Captions are now: LabHeading - UserID and Password Window LabUserID - UserID LabPassword - Password The edit field names are TxtUSerID and TxtPassword. The button names and captions are: BtnAdd - ADD BtnClose - CLOSE
146
In order to add code to handle events such as clicking on a button we can get to the event code by double clicking on the button on the form. The image below is from double clicking on the ADD button.
The following image shows code that has been added to obtain and display the userid and password fields when the ADD button is clicked, when the CLOSE button is clicked the window is closed. Note we have now saved the form with the name FormUserPwd.
147
Note, you can always return to the code for the form by selecting Code from the Testpartner View menu while in the form.
148
Activation of a UserForm
In order to display a userform from within a script the form must be included with the standard $TPInclude statement and then the show method is used to display the form and pass control to that form. Control will return to the script when the form is hidden as in the close button code above.
149
Instructions: STEP 1: Create a script (Password) using the InputBox function to request the input of a password for the userid dtl STEP 2: Use the debug options to step through the script.
150
Examples: Script Option Explicit Sub Main() Dim Reply As String Reply = InputBox("Input password for Userid dtl", "Password Input") End Sub Display
151
However, even if we switch off logging then the password will still be contained within the script, and thus easily accessible. One method around this is to encrypt the password and then store it in the registry (or a file) using the UserId as a key value to lookup the password and decrypt it when required.
Function Decrypt(Password As String) As String Dim I As Integer Dim ParLen As Long Dim Decoded As String Dim NextChar As String Dim Ansi As Long Dim SaveLogging As Boolean SaveLogging = Playback.Logging Playback.Logging = False Decoded = "" For I = 1 To Len(Password) NextChar = Mid(Password, I, 1) Ansi = Asc(NextChar) Ansi = Ansi + I Decoded = Decoded & Chr(Ansi) Next Decrypt = Decoded Playback.Logging = SaveLogging End Function With the above two functions stored in Testpartner as a Shared Module the Encrypt and Decrypt functions become available for any script to use. Because we do not want the decryption or encryption process logged, the logging has been turned off at the start of the code. However if logging was already off we do not want to switch it back on by mistake at the end of the code. To handle this, the current logging status is stored in the variable SaveLogging, and then logging is set back to this status at the end of the functions. The following simple code using the above functions should display an encrypted version of pass as o_po and then convert it back to pass. Dim Original As String Dim Encoded As String Dim Decoded As String Original = "pass" Encoded = Encrypt(Original) MsgBox (Encoded) Decoded = Decrypt(Encoded) MsgBox (Decoded)
153
154
section is required and a string value, this is the section within appname where the information will be looked for. key is required and a string value, it is the key value to be used to retrieve the stored data from the above section. default is a default value to be returned if the requested value is not found. GetSetting returns a string. It is recommended that the reader should also look at commands GetAllSettings and DeleteSetting.
155
Instructions: STEP 1: Copy script EX11 to script EX13, within the script change the Run Signon to Run SecureSignon. Copy script Signon to SecureSignon. STEP 2: Implement the encryption and decryption routines from the above chapter as a shared module called security. STEP 3: Modify the Password script from EX12 to encrypt the password and save it in the registry using an Appname of QADemoWeb, a section of Passwords and the userid (dtl) as a key. STEP 4: Hide the code in script Password from the log by disabling the logging. STEP 5: Build a loop handling several userids in script Password. STEP 6: Modify the SecureSignon script to obtain the password from the registry, decode it, and then use this for logging in to QADemo Web. Ensure the password does not appear in the log. STEP 7: Ensure all your code from EX13 is still functioning correctly. Examples Password Script '$TPInclude "security" Option Explicit Sub Main() Dim Reply As String Dim Encoded As String Dim User(4) As String Dim Index As Integer User(0) = "John" User(1) = "Fred" User(2) = "dtl"
156
Encoded = Encrypt(Reply) SaveSetting "QADemoWeb", "Passwords", User(Index), Encoded Index = Index + 1 Wend End Sub SecureSignon Script HTMLBrowser("Caption='QADemo - Login'").Attach HTMLEditBox("Signon Window User Id Edit").SetText "dtl" SaveLogging = Playback.Logging Playback.Logging = False Encoded = GetSetting("QADemoWeb", "Passwords", "dtl", "") Decoded = Decrypt(Encoded) HTMLEditBox("Signon Window Password Edit").SetText Decoded Platback.Logging = SaveLogging HTMLRadioButton("Signon Window Paris Radio").Click HTMLButton("OK HTMLButton").Click
157
158
This displays the References Window where you must ensure that the Microsoft Scripting Runtime is selected.
The FileSystemObject
Once the above option has been selected you can reference the FileSystemObject. This is a very flexible object which provides methods and properties for accessing every folder and file on the host computer. We shall use this object to test for the existence of a file and then to create a TextStream object for file access. However this is only a small part of the objects abilities and the reader is recommended to do further reading. First in our script we must create a new FileSystemObject, this is achieved by the following code: Dim Fsys as New Scripting.FileSystemObject Or simply: Dim Fsys As New FileSystemObject After this when we type the Fsys followed by a period we are presented with a list of the components of the scripting object. The object we are interested in from this list is FileExists as we wish to test if a file exists or not. The code in our script to create the object and test if a file exists or not would look similar to the following: 159
Option Explicit Sub Main() Dim Fsys As New FileSystemObject Dim Filename As String Filename = "C:\Temp\Test.txt" If Fsys.FileExists(Filename) Then MsgBox ("File Exists") Else MsgBox ("File Missing") End If The above code is testing for the existence of a file C:\Temp\Test.txt and displays a message box stating if the file exists or not.
160
Option Explicit Sub Main() Dim FObj As TextStream Dim Fsys As New FileSystemObject Dim Filename As String Filename = "C:\Temp\Test.txt" If Fsys.FileExists(Filename) Then MsgBox ("File Exists") Set FObj = Fsys.OpenTextFile(Filename, ForAppending) Else MsgBox ("File Missing") Set FObj = Fsys.CreateTextFile(Filename, True) End If FObj.WriteLine ("This is Line One") FObj.WriteLine ("This is Line Two") FObj.Close End Sub To open and read the file is also straight forward, we use the OpenTextFile method to open the file for input and the Readline method to read each line. If we add the following code to the end of the code above (before the End Sub) it will read and display the information written to the file. Set FObj = Fsys.OpenTextFile(Filename, ForReading) While FObj.AtEndOfStream = False TLine = FObj.ReadLine MsgBox ("Read: " & TLine) Wend FObj.Close
161
162
. . .
If TempPrice = DealerPrice Then UserCheck "Dealer Price", True, "Valid Dealer Price: " & DealerPrice Fobj.WriteLine (" Valid DealerPrice: " & DealerPrice) Else UserCheck "Dealer Price", False, "INValid Dealer Price: " & DealerPrice _ & "Expected: " & TempPrice Fobj.WriteLine ("INVALID Dealer Price: " & DealerPrice & "Expected: " & TempPrice) End If HTMLButton("Add HTMLButton").Click If Wait(30, "Add Car Reference Field Blank", tpWaitSeconds) = True Then UserCheck "AddCarsEvents", True, "Car Reference " & TD.DataItem("Ref") & "Added to DB" Fobj.WriteLine (" Added to Database") Else UserCheck "AddCarsEvents", False, "Car Reference " & TD.DataItem("Ref") Fobj.WriteLine (" Database write FAILURE!") End If Wend TD.CloseData Fobj.Close
Example Testlog file ========== 7/12/2003 12:01:46 PM ========== =============================================================== Car Reference: car-1889 Make: Ford Taurus Valid DealerPrice: 14000 Added to Database =============================================================== Car Reference: car-996 Make: Plymouth Breeze Valid DealerPrice: 11025 Added to Database =============================================================== Car Reference: car-1997 Make: Chrysler Sebring Valid DealerPrice: 16145.75 Added to Database =============================================================== Car Reference: car-889 Make: Ford Taurus
163
Valid DealerPrice: 14000 Added to Database =============================================================== Car Reference: car-1996 Make: Plymouth Breeze Valid DealerPrice: 11025 Added to Database =============================================================== Car Reference: car-997 Make: Chrysler Sebring Valid DealerPrice: 16145.75 Added to Database
164
To fully cover SQL and DB access is beyond the scope of this manual, so we shall cover enough to enable a Database to be accessed and its contents checked.
165
Set Cnn = New ADODB.Connection Cnn.ConnectionString = "DSN=qademo;UID=;PWD=;" We can execute an sql statement and store the results into a recordset as follows: MySql = "Select * From CarList Set RS = Cnn.Execute(MySql) We can then examine the results in the record set with the following: Do Until RS.EOF MsgBox RS("Ref") & " " & RS("Make") RS.MoveNext Loop RS.Close It is recommended that the user examines the options available when typing RS. such as BOF, MoveFirst,MoveLast, etc. The QADemo database consists of the following three tables : CarList Ref Make Engine Size Year Door Cost Discount QuantityA QuantityB QuantityC Cond1 Cond2 Cond3 Cond4 Cond5 Cond6 Customers Account Number Name Address Details User Password UserName
166
167
Examples: SQLDatabaseCheck Script '$TPInclude "ErrorHandler" '$TPInclude "TestDataFunctions" Option Explicit Sub Main() Dim oe As TOnError Set oe = OnError("QADemoErrorFunction") Dim TD As New TestDataFunctions Dim Cnn As ADODB.Connection 'stores the connection object Dim RS As ADODB.Recordset 'stores a recordset object Dim MySql As String Dim ErrorCount As Integer Set Cnn = New ADODB.Connection Cnn.ConnectionString = "DSN=qademo;" Cnn.Open ErrorCount = 0 TD.OpenData ("C:\Temp\cars.csv") While TD.ReadNextDataRecord = True
MySql = "Select * From CarList Where Ref = " & "'" & TD.DataItem("Ref") & "'"
Set RS = Cnn.Execute(MySql) If RS.EOF = True Then ' Reference was not found UserCheck "SQL Database", False, TD.DataItem("Ref") & " Not Found." ErrorCount = ErrorCount + 1 End If Wend If ErrorCount = 0 Then UserCheck "SQL Database", True, "All items found in database" End If TD.CloseData End Sub
168
Chapter 16 Screenshots
While testing it can be useful to take a screenshot, possibly to verify the screen is as expected, or more likely to provide additional information in the event of an error. In this chapter we will assume that we want to take a screenshot after an error has occurred, write that screen image out in a word document allowing for any previous files, and log the name of the word file to our script log. Taking a screenshot can be achieved by recording typing the printscreen key on the keyboard. This will give recorded code similar to the following:
PrintScrn
Window("Microsoft Internet Explorer").Attach Window.Type "{PrintScrn}" Here we were in the Internet Explorer when we recorded the printscreen. You must be sure you can attach to this window whenever you are going to execute this code if you include the attach statement. Normally you will already be attached to a window and the Window.Type {PrintScrn} will be all that is required. It is worth mentioning that because the PrintScn is enclosed in curly brackets it is treated as a special keyboard function and not a string value. Other special keys will record in a similar way, for example: the End key gives {ExtEnd}, Ctrl-C and Ctrl-V give {Ctrl C} and {Ctrl V} respectively. Once we have our Screenshot stored on the computer clipboard, we can record loading an application such as word in which to save this. We add the image to a document by using the Ctrl-V keyboard option to paste the image into the document. Then record saving the document to the required folder on disk, and close everything down as required.
Storing in Files
The above process will work fine once, but we need to modify the filename we save the image in so as not to overwrite any existing files. The following code assumes the output filename has the format ScreenDumpxxxx.doc where the xxxx is a number starting at 0001 and rising to a possible 9999. It uses the FileSystemObject we were introduced to in Chapter 14, and uses the FileExists method of that object to check if a filename already exists. The filename to check for is created by concatenating together 3 169
components, the full path filename up to the 4 digit number, the 4 digit number derived from a For loop, and finally the word .doc extension. As soon as it is found that the file does not exist then we exit the for loop with the Exit For command, and the variable filename contains the full filename to use for saving the captured screen shot. Dim FObj As New FileSystemObject Dim Filename As String Dim Prefix As String Dim Suffix As String Dim Count As Integer Prefix = "C:\Errors\ScreenDump" For Count = 1 To 9999 Step 1 Suffix = Format(Count, "0000") Filename = Prefix & Suffix & ".doc" If FObj.FileExists(Filename) = False Then Exit For End If Next Finally we can log to our script log the name of the file containing the screenshot using the standard TestLog.Comment command. TestLog.Comment ("Screenshot in file: " & Filename)
170
Exercise 16 Screenshots
Objective: To write a function which takes a screen dump and outputs it to a word file. To add the function to the standard error handling function. Instructions: STEP 1: Manually do a print screen, then in a script record loading Microsoft word, paste the screen dump into the word document, and save the screen dump as a file (C:\Temp\ScreenDump0001). STEP 2: Delete the saved file, at the beginning of the script use the Currently Active Window code in the appendix to attach to the currently active window and add a Window.Type "{PrintScrn}". Ensure the script works. STEP 3: Add the code to calculate the next filename to use (see chapter above) and insert into script. Run script several times to ensure it works. STEP 4: Add a run statement for this script to the beginning of the error handling function "QADemoErrorFunction" in shared module "ErrorHandling" developed in chapter 11. This will cause a screendump to be taken on every error.
171
Examples ScreenDump Script '$TPInclude "ErrorHandler" Private Declare Function GetForegroundWindow Lib "user32" () As Long Option Explicit Sub Main() Dim oe As TOnError 'Set oe = OnError("QADemoErrorFunction") Dim FObj As New FileSystemObject Dim Filename As String Dim Prefix As String Dim Suffix As String Dim Count As Integer
Dim lHwnd As Long Dim WindowName As String lHwnd = GetForegroundWindow WindowName = Window("hwnd=" & lHwnd).AttachName
Window(WindowName).Attach Window.Type "{PrintScrn}" '----------------------'Load Microsoft Word Window("Window").Attach Button("Caption=Start").Click Window.PopupMenuSelect "Programs~Microsoft Word" Window("Microsoft Word - Document").Attach Window.Type "{Ctrl V}" 'Paste in the screen Window("Microsoft Word - Document").Attach Window.MenuSelect "File~Save As" Window("Save As Window").Attach '------------------172 'Take the screen dump
'Calculate the next filename to use Prefix = "C:\Temp\ScreenDump" For Count = 1 To 9999 Step 1 Suffix = Format(Count, "0000") Filename = Prefix & Suffix & ".doc" If FObj.FileExists(Filename) = False Then Exit For End If Next '------------------'Save as new filename and shutdown word GUIObject("ClassName=RichEdit20W Caption=''").Attach GUIObject.Type Filename Window("Save As Window").Attach Window.BitmapSelect "Save As2" 'Note! following object needs changing for diff. window titles Window("Microsoft Word - ScreenDump Window").Attach Window.MenuSelect "File~Exit" TestLog.Comment ("Screenshot in file: " & Filename) End Sub
173
ScrollBars
Scrollbars can vary according to the application they are contained in. For example in MSWord Scrollbars are objects, however in Notepad they are part of the editbox. This difference limits what you can do with Scrollbars in Notepad. With a Scrollbar as an object the following functions are available: To obtain the maximum value that can be scrolled to (ie end of document) Height = ScrollBar("Index=1").Height To scroll to the start of a document: Position = 0 ScrollBar("Index=1").SetPosition Position To scroll to the very end of a document: Position = Height ScrollBar("Index=1").SetPosition Position 174
Working with scroll bars in Notepad. Notepad must be opened. The scroll bar is part of the edit box and the size of the edit box determines the bottom position of the scrollbar. You can not use the "height" function but must use the "linecount" function to determine how far you can scroll in Notepad. EditBox("Index=1").Attach Count = EditBox("Index=1").LineCount Scroll to the bottom of the document: EditBox("Index=1").Attach EditBox.Scroll Count, tpScrollVertical Scroll to the top of the document: EditBox("Index=1").Attach EditBox.Scroll 0, tpScrollVertical
Checkboxes
While the standard checkbox click command is fine for setting a checkbox: CheckBox("Caption=Rad&io").Click It does not allow you to clear an existing check from the checkbox. It is worth considering using the setcheck method on a checkbox as this can both set a checkbox and clear it: If TD.DataItem("Radio") = "on" Then CheckBox("Caption=Rad&io").SetCheck (True) set the checkbox Else CheckBox("Caption=Rad&io").SetCheck (False) clear the checkbox End If
175
Loading an application
While recording the loading of a program through the menu system is fine, there are times when an application may not be available through the menus, or it is required to load the program faster. This can be achieved by a combination of the chdir command, which sets the working directory, and the shell command which loads the program:
ChDir "C:\Program Files\Compuware\Demos" Ret = Shell("C:\Program Files\Compuware\Demos\QADemo.exe", vbNormalFocus)
End Sub
176
Search Functions
It is often required to find if a value exists in a window where we do not have individual fields that can be captured and examined (Chapter 10). If the functions below are included as a module then the window can be captured and the functions used to check if the required value is in that window. Textselect (Chapter 7) can be used to select the entry if required. Sub Main() Dim CapturedWindow As String Dim LineNo As Integer Window("Display Details Window").Attach CapturedWindow = Window("Display Details Window").CaptureText LineNo = FnFindLine(CapturedWindow, "Ref 100111") If LineNo <> 0 Then use textselect to select the entry in the window Window("Display Details Window").TextSelect ("Ref 100111") Else MsgBox Value not found End If .. . .. End Sub '*********************************************************************** Search the string ToBeSearched for the string SearchFor and return how many are found '*********************************************************************** Function FnStringSearch(ToBeSearched As String, SearchFor As String) As Integer Dim StartPos As Integer Dim FoundCount As Integer Dim Pos As Integer StartPos = 1 FoundCount = 0 While StartPos + Len(SearchFor) - 1 <= Len(ToBeSearched) Pos = 0 Pos = InStr(StartPos, ToBeSearched, SearchFor) If Pos <> 0 Then StartPos = Pos + Len(SearchFor) FoundCount = FoundCount + 1 177
Else StartPos = Len(ToBeSearched) + 1 ' force exit of while End If Wend FnStringSearch = FoundCount End Function '*********************************************************************** 'This function processes the Inputstring to detect which line the first 'occurrence of Searchvalue is found on. 1st Line is 1, a 0 means not found '*********************************************************************** Function FnFindLine(ByVal InputString As String, SearchValue As String) As Integer Dim LineArray() As String Dim crlf As String Dim Count As Integer Dim LineLen As Integer Dim StringLength As Integer Dim LineNumber As Integer Dim I As Integer LineNumber = 0 crlf = Chr(13) & Chr(10) 'Only continue if the SearchValue exists in the InputString, return 0 otherwise '-------------------------------------------------------------------------------------If FnStringSearch(InputString, SearchValue) > 0 Then 'Obtain the string length and the line length '------------------------------------------StringLength = Len(InputString) LineLen = InStr(1, InputString, crlf) + 1 'Create an array of lines from the string splitting them on a crlf '-----------------------------------------------------------------LineArray = Split(InputString, crlf) LineNumber = UBound(LineArray) 'Now search line by line to see which line has the required string in it '----------------------------------------------------------------------For I = 0 To LineNumber 'Note 1st LineNumber was 0 as array starts at 0 Count = FnStringSearch(LineArray(I), SearchValue) If Count > 0 Then
178
Exit For End If Next FnFindLine = I + 1 ' This is the line number starting at 1 Else FnFindLine = 0 ' Value was not found anywhere End If End Function
179