Test Object Model Concept

The test object model is a large set of object types or classes that QuickTest uses to represent the objects in your application. Each test object class has a list of properties that can uniquely identify objects of that class and a set of relevant methods that QuickTest can record for it.

A test object is an object that QuickTest creates in the component to represent the actual object in your application. QuickTest stores information about the object that will help it identify and check the object during the run session.

A run-time object is the actual object in your application on which methods are performed during the run session.

When you perform an operation on your application while recording, QuickTest:

  • identifies the QuickTest test object class that represents the object on which you performed the operation and creates the appropriate test object
  • reads the current value of the object's properties in your application and stores the list of properties and values with the test object
  • chooses a unique name for the object, generally using the value of one of its prominent properties
  • records the operation that you performed on the object using the appropriate QuickTest test object method

FW: Getting Standard Text without text recognition

The code below shows how you can get the text from any standard object without using text recognition in Quicktest

Standard Examples

'Get text from a ListView - report style (for example, Windows Explorer)

msgbox Window("C:\Program Files\Mercury").WinListView("SysListView32").GetSubItem(1,2)

'Get text from a toolbar

msgbox Window("C:\Program Files\Mercury").WinToolbar("ToolbarWindow32").GetItem(1)

'Text of a message-box, the Static control is not in the object repository/shared object ' 'repository

set StatObj = Dialog("DlgTB").Dialog("DlgTB").Static("nativeclass:=Static","Index:=1")

msgbox StatObj.GetROProperty("text")

Web Example

' An example for a Web Table (in the Mercury Tour site)

Set Cell = Browser("Welcome: Mercury Tours").Page("Select a Flight: Mercury").WebTable("RETURN").ChildItem(3, 2, "WebElement", 0)

Msgbox Cell.GetROProperty("innertext")

Visual Basic Example

'Retrieving the text of a label in a VB form: (There is no Test Object for a label)

msgbox VbWindow("VBForm1").Object.Controls("Label1").caption

.NET Example

'Get the text of items in a CheckListBox (has no Test Object)

'Get run-time object reference

Set CustList = SwfWindow("Win").SwfObject(ìlst").Object

'Get Items collection

Set ListItems = CustList.get_Items()

'Get Items count

ItemsCount = ListItems.Count

'Loop over all items

For i = 0 to ItemsCount-1

text = text & ListItems.Item(i)

Next

ActiveX Example

' This example will retrieve the text from the Visual Basic Flight 1A sample application's flight grid

' This retrieves the flight number from the 3rd row.

VbWindow("VbWindow").VbWindow("VbWindow").AcxTable("Grid Control").Object.Row = 3

VbWindow("VbWindow").VbWindow("VbWindow").AcxTable("Grid Control").Object.Col = 0

msgbox VbWindow("VbWindow").VbWindow("VbWindow").AcxTable("Grid Control").Object.Text

Highlighting Objects code for QTP

The following function uses a Win32 function to draw a rectangle that will highlight a given object using the object coordinates

' Declare necessary APIs

Extern.Declare micHwnd, "GetDesktopWindow", "User32.DLL", "GetDesktopWindow"

Extern.Declare micULong, "GetWindowDC", "User32.DLL", "GetWindowDC", micHwnd

Extern.Declare micInteger, "ReleaseDC", "User32.DLL", "ReleaseDC", micHwnd, micULong

Extern.Declare micULong, "CreatePen", "Gdi32.DLL", "CreatePen", micInteger, micInteger, micDword

Extern.Declare micInteger, "SetROP2", "Gdi32.DLL", "SetROP2", micULong, micInteger

Extern.Declare micULong, "SelectObject", "Gdi32.DLL", "SelectObject", micULong, micULong

Extern.Declare micULong, "DeleteObject", "Gdi32.DLL", "DeleteObject", micULong

Extern.Declare micULong, "GetStockObject", "Gdi32.DLL", "GetStockObject", micInteger

Extern.Declare micULong, "Rectangle", "Gdi32.DLL", "Rectangle", micULong, micInteger, micInteger, micInteger, micInteger

Function HighlightRect (X, Y, W, H, Times)

' Get the Desktop DC

hDC = Extern.GetWindowDC (Extern.GetDesktopWindow)

' Create a three pixel wide pen

hPen = Extern.CreatePen (6, 3, RGB(0, 0, 0)) ' PS_INSIDEFRAME, 3 , RGB(0, 0, 0)

Extern.SetROP2 hDC, 6 ' hDC, R2_NOT

Extern.SelectObject hDC, hPen

' Use an empty fill

Extern.SelectObject hDC, Extern.GetStockObject (5) ' NULL_BRUSH

' Do the highlight

For i = 0 to Times * 2 + 1

Extern.Rectangle hDC, X, Y, X + W, Y + H

wait 0, 50

Next

' CleanUp

Extern.ReleaseDC Extern.GetDesktopWindow, hDC

Extern.DeleteObject hPen

End Function

QuickTest Professional Object Model Hierarchy

The following example illustrates how to use QuickTest Professional's test object hierarchy to write better scripts.

If you have a table where you need to click on the Details link inside the row that begins with the text Record number 1234, you can use the following code that performs the following:

  • Find the correct row by iterating through each row and checking the value of the first cell.
  • After finding the row, iterate through all the cells in the row and find the link you are looking for.

BeginRowStr = "Record number 1234"

rowCount = Browser("Finance").Page("Finance").WebTable("Records").RowCount

For i=2 to rowCount

cellData = Browser("Finance").Page("Finance").WebTable("Records").GetCellData (i,1)

If cellData = BeginRowStr Then

colCount = Browser("Finance").Page("Finance").WebTable("Records").ColumnCount (i)

For j=2 to colCount

cellData = Browser("Finance").Page("Finance").WebTable("Records").GetCellData (i,j)

If cellData = "Details " Then

set cellLink = Browser("Finance").Page("Finance").WebTable("Records").ChildItem (i, j, "Link", 0)

cellLink.Click

Exit For ' Exit inner loop

End If

Next

Exit For ' Exit outer loop

End If

Next

Another way to perform this is by using the hierarchical object model of QuickTest Professional.

You can find the correct row by using the description of the row element in the HTML (having the TR html tag), and stating that the element should have the text Record number 1234.*. The constant text will verify that this is the correct row (even if the text is in more then one cell), and the .* will match all the rest of text of that row. After finding the correct row, click on the link that has the text Details.

With Browser("Finance").Page("Finance").WebTable("Records")

.WebElement("html tag:=TR", "innertext:=" & BeginRowStr & ".*").Link("html tag:=A", "innertext:=Details ").Click

End With

Enumerating Application Objects

The code below illustrates one way of enumerating the application objects while performing an operation on each object.

Function EnumerateApp(ParentObj, Desc, OperationMethod, PostOperationMethod, RestoreMethod)

dim ObjCol, CurrentObj, idx

idx = 0

' Retrieve a collection of all the objects of the given description

Set ObjCol = ParentObj.ChildObjects(Desc)

Do While (idx < ObjCol.Count)

' Get the current object

set CurrentObj = ObjCol.item(idx)

' Perform the desired operation on the object

eval("CurrentObj." & OperationMethod)

' Perform the post operations (after the object operation)

eval(PostOperationMethod & "(ParentObj, CurrentObj)")

' Return the application to the original state

eval(RestoreMethod & "(ParentObj, CurrentObj)")

idx = idx + 1

' Retrieve the collection of objects

' (Since the application might have changed)

Set ObjCol = ParentObj.ChildObjects(Desc)

Loop

End Function

' ********************************** An Example of usage **********************

' Report all the pages referred to by the current page

' ***********************************************************************************

Function ReportPage(ParentObj, CurrentObj)

dim FuncFilter, PageTitle

PageTitle = ParentObj.GetROProperty("title")

FuncFilter = Reporter.Filter

Reporter.Filter = 0

Reporter.ReportEvent 0, "Page Information", "page title " & PageTitle

Reporter.Filter = FuncFilter

End Function

Function BrowserBack(ParentObj, CurrentObj)

BrowserObj.Back

End Function

' Save the Report Filter mode

OldFilter = Reporter.Filter

Reporter.Filter = 2 ' Enables Errors Only

' Create the description of the Link object

Set Desc = Description.Create()

Desc("html tag").Value = "A"

Set BrowserObj = Browser("creationtime:=0")

Set PageObj = BrowserObj.Page("index:=0")

' Start the enumeration

call EnumerateApp(PageObj, Desc, "Click", "ReportPage", "BrowserBack")

Reporter.Filter = OldFilter ' Returns the original filter

Using Data Table Formulas

This page provides some useful formulas that can be used in the Data Table. Any combination of the formulas below is acceptable. The formulas refer to the data in cell A1 but may be applied to any cell.

For more information on Data Table formulas, refer to Microsoft Excel documentation. All Microsoft Excel formulas can be used in the Data Table.

First word in a sentence:

=LEFT(A1,SEARCH("",A1,1))

First three words in a sentence:

=LEFT(A1,SEARCH("@",SUBSTITUTE(A1,"","@",3),1))

Part of the sentence starting with the fourth word:

=MID(A1,SEARCH("@",SUBSTITUTE(A1,"","@",3),1),LEN(A1))

The part of the sentence starting with "word":

=MID(A1,SEARCH("word",A1,1),LEN(A1))

Check if two strings are equal:

=EXACT(A1,"text2")

Duplicate the string three times:

=REPT(A1,3)

Concatenation of two strings:

="Hello " & "There"

Today's date:

=TODAY()

Generate a random uppercase letter:

=CHAR((RAND() *26) +65)

Using the Dictionary Object in QTP

As an alternative to using environment variables to share values between actions, you can use the Dictionary object. The Dictionary object enables you to assign values to variables that are accessible from all actions (local and external) called in the test in which the Dictionary object is created.

'In order to have IntelliSense for the Dictionary object, and have it recognized by other actions, it is added to the registry

Dim WshShell

Set WshShell =CreateObject("WScript.Shell")

WshShell.RegWrite "HKCU\Software\Mercury Interactive\QuickTest Professional\MicTest\ReservedObjects\GlobalDictionary\ProgID", "Scripting.Dictionary","REG_SZ"

Set WshShell = Nothing

' After updating the registry, you must close and reopen QuickTest Professional.

' ***********************************************************************************

' Available methods

' -----------------------------

' Exists

GlobalDictionary.Exists(<Key Name>) ' Returns True or False

' Remove

GlobalDictionary.Remove(<Key Name>) ' Remove a specific key

' RemoveAll

GlobalDictionary.RemoveAll ' Removes all keys

' Add

GlobalDictionary.Add <Key Name>, <Value> ' Create a new key and assigns its value

' Item

GlobalDictionary.Item(<Key Name>) ' Gets/Sets a key value

How QuickTest Identifies Objects During the Run Session

QuickTest also uses a very human-like technique for identifying objects during the run session.

Suppose as a continuation to the experiment, Johnny is now asked to identify the same "item" he initially identified but in a new, yet similar environment.

The first photograph he is shown is the original photograph. He searches for the same caucasian girl, about eight years old, with long, brown hair that he was asked to remember and immediately picks her out. In the second photograph, the children are playing on the playground equipment, but Johnny is still able to easily identify the girl using the same criteria.

Similarly, during a run session, QuickTest searches for a run-time object that exactly matches the description of the test object it learned while recording. It expects to find a perfect match for both the mandatory and any assistive properties it used to create a unique description while recording. As long as the object in the application does not change significantly, the description learned during recording is almost always sufficient for QuickTest to uniquely identify the object. This is true for most objects, but your application could include objects that are more difficult to identify during subsequent run sessions.

Consider the final phase of Johnny's experiment. In this phase, the tester shows Johnny another photograph of the same family at the same location, but the children are older and there are also more children playing on the playground. Johnny first searches for a girl with the same characteristics he used to identify the girl in the other pictures (the test object), but none of the caucasian girls in the picture have long, brown hair. Luckily, Johnny was smart enough to remember some additional information about the girl's appearance when he first saw the picture the previous week. He is able to pick her out (the run-time object), even though her hair is now short and dyed blond.

How is he able to do this? First, he considers which features he knows he must find. Johnny knows that he is still looking for a caucasian female, and if he were not able to find anyone that matched this description, he would assume she is not in the photograph.

Once he has limited the possibilities to the four caucasian females in this new photograph, he thinks about the other characteristics he has been using to identify the girl—her age, hair color, and hair length. He knows that some time has passed and some of the other characteristics he remembers may have changed, even though she is still the same person.

Thus, since none of the caucasian girls have long, dark hair, he ignores these characteristics and searches for someone with the eyes and nose he remembers. He finds two girls with similar eyes, but only one of these has the petite nose he remembers from the original picture. Even though these are less prominent features, he is able to use them to identify the girl.

QuickTest uses a very similar process of elimination with its Smart Identification mechanism to identify an object, even when the recorded description is no longer accurate. Even if the values of your test object properties change, QuickTest maintains your component's reusability by identifying the object using Smart Identification. For more information on Smart Identification,

The remainder of this help assumes familiarity with the concepts presented here, including test objects, run-time objects, object properties, mandatory and assistive properties, and Smart Identification. An understanding of these concepts will enable you to create well-designed, functional components for your application.