You are on page 1of 25

Descriptive Programming Descriptive Programming

Entering / Providing objects information directly into the test script is called Descriptive Programming. In this method of script creation, we no need to have Object Repositories. Advantages: a) Descriptive Programming based Test scripts are faster in execution than Repository based Test scripts. b) Scripts are portable (we can run these scripts from any machine easily) c) Maintenance is easy (less amount of resources) d) We can start Test Execution process even though Application is not ready. Descriptive programming is basically 2 types. Static Programming Dynamic Programming

1. 2.

Static Programming
In this style of script generation, we provide objects information directly into the script. Ex: Invokeapplication C:Program FilesHPQuickTest Professionalsamplesflightappflight4a.exe dialog(text:=Login).Activate dialog(text:=Login).Winedit(attached text:=Agent Name:).Set asdf dialog(text:=Login).Winedit(attached text:=Password:).Set mercury dialog(text:=Login).Winbutton(text:=OK,width:=60).Click Note: Dialog, WinEdit and WinButton Test Objects text, attached text Property names Login, Agent Name:, Password:, OK Property values or Logical Names of the Object Activate, Set, Setsecure, Click Methods Note2: If we feel one property information is not sufficient for recognizing the object uniquely, then we can provide more properties information by separating with commas. Note 3: If we want to get objects information (Test objects, properties and values), we can use object spy feature. This feature is available in Tools Menu, in local repository and in repository manager. If we want maintain Objects information in centralized location then we can use Constants. Steps: Creating Constants: Const Login=text:=Login, Agent=attached text:=Agent Name: Const Pwd =attached text:=Password:, Ok=text:=OK Note: we can declare no of Constants in a line by separating with Camas (,), if we take other line then we have to use Const Statement again. Creating a Library file Place Constants in Notepad and save as .vbs file Associate the Library file to QTP (File->Settings->Resources-> Click add (+) icon-> Browse path of the Library file->Click Apply and click Ok buttons Otherwise, we can load the library file during run-time Syntax: ExecuteFile Path of the Library file(.vbs) After that create the Test Script using Constants Creating the Test Script using Constants: Invokeapplication C:Program FilesHPQuickTest Professionalsamplesflightappflight4a.exe Dialog(Login).Activate Dialog(Login).Winedit(Agent).Set asdf Dialog(Login).Winedit(Pwd).Set mercury Dialog(Login).Winbutton(Ok).Click Advantages: If we maintain Object Information in the centralized location, then we can handle modifications easily. -

1. 2. 3. 4.

Dynamic Programming
In this style of script generation, first we create description objects, provide properties information and use description objects in the test script. Creating Properties Collection Objects Set oLogin=description.Create Set oAgent=description.Create Set oPassword=description.Create Set oOk=description.Create Entering Properties Information into Objects

oLogin(text).value=Login oLogin(width).value=320 oLogin(height).value=204 oAgent(attached text).value=Agent Name: oPassword(attached text).value=Password: oOk(text).value=OK Generating Tests using Properties collection Objects Invokeapplication C:Program FilesHPQuickTest Professionalsamplesflightappflight4a.exe Dialog(oLogin).Activate Dialog(oLogin).Winedit(oAgent).Set asdf Dialog(oLogin).Winedit(oPassword).Set mercury Dialog(oLogin).Winbutton(oOK).Click Note1: Create Description objects and put into one library file, by associating that library file, we can generate tests. Note2: Dynamic programming is some difficult in preparation than static programming but maintenance is very easy. In this style of script creation also, we can maintain Objects information in the Centralized location by putting collection objects in a Library file.

Descriptive programming
In this post we will discuss: Introduction to Descriptive Programming. How to write Descriptive Programming? When and Where to use Descriptive programming? Some points to note with Descriptive Programming. Introduction to Descriptive Programming: Descriptive programming is used when we want to perform an operation on an object that is not present in the object repositor y. There can be various valid reason to do so. We will discuss them later in this article. How to write Descriptive Programming?

There are two ways in which descriptive programming can be used 1. By giving the description in form of the string arguments. 2. By creating properties collection object for the description. 1. By giving the description in form of the string arguments. This is a more commonly used method for Descriptive Programming. You can describe an object directly in a statement by specifying property:=value pairs describing the object instead of specifying an objects name. The general syntax is: TestObject("PropertyName1:=PropertyValue1", "..." , "PropertyNameX:=PropertyValueX") TestObjectthe test object class could be WebEdit, WebRadioGroup etc. PropertyName:=PropertyValuethe test object property and its value. Each property:=value pair should be separated by commas and quotation marks. Note that you can enter a variable name as the property value if you want to find an object based on property values you retrieve during a run session. Consider the HTML Code given below: <--!input type="textbox" name="txt_Name"--> <--!input type="radio" name="txt_Name"--> Now to refer to the textbox the statement would be as given below

Browser(Browser).Page(Page).WebEdit(Name:=txt_Name,html tag:=INPUT).set Test And to refer to the radio button the statement would be as given below Browser(Browser).Page(Page).WebRadioGroup(Name:=txt_Name,html tag:=INPUT).set Test If we refer to them as a web element then we will have to distinguish between the 2 using the index property Browser(Browser).Page(Page).WebElement(Name:=txt_Name,html tag:=INPUT,Index:=0).set Test Refers to the textbox Browser(Browser).Page(Page).WebElement(Name:=txt_Name,html tag:=INPUT,Index:=1).set Test Refers to the radio button To determine which property and value pairs to use, you can use the Object Spy: 1. Go to Tools -> Object Spy. 2. Select the "Test Object Properties" radio button. 3. Spy on the desired object. 4. In the Properties list, find and write down the properties and values that can be used to identify the object.

2. By creating properties collection object for the description. Properties collection also does the same thing as string arguments. The only difference is that it "collects" all the properties of a particular object in an instance of that object. Now that object can be referenced easily by using the instance, instead of writing "string arguments" again and again. It is my observation that people find "string arguments" [1] method much easier and intuitive to work with. To use this method you need first to create an empty description Dim obj_Desc Not necessary to declare Set obj_Desc = Description.Create Now we have a blank description in obj_Desc. Each description has 3 properties Name, Value and Regular Expression. obj_Desc(html tag).value= INPUT When you use a property name for the first time the property is added to the collection and when you use it again the property is modified. By default each property that is defined is a regular expression. Suppose if we have the following description obj_Desc(html tag).value= INPUT obj_Desc(name).value= txt.* This would mean an object with html tag as INPUT and name starting with txt. Now actually that .* was considered as regular expression. So, if you want the property name not to be recognized as a regular expression then you need to set the regularexpression property as FALSE obj_Desc(html tag).value= INPUT obj_Desc(name).value= txt.* obj_Desc(name).regularexpression= txt.* This is how we create a description. Now below is the way we can use it Browser(Browser).Page(Page).WebEdit(obj_Desc).set Test When we say .WebEdit(obj_Desc) we define one more property for our description that was not earlier defined that is its a text box (because QTPs WebEdit boxes map to text boxes in a web page). If we know that we have more than 1 element with same description on the page then we must define index property for the that description Consider the HTML code given below <--!input type="textbox" name="txt_Name"--> <--!input type="textbox" name="txt_Name"--> Now the html code has two objects with same description. So distinguish between these 2 objects we will use the index property. Here is the description for both the object

For 1st textbox: obj_Desc(html tag).value= INPUT obj_Desc(name).value= txt_Name obj_Desc(index).value= 0 For 2nd textbox: obj_Desc(html tag).value= INPUT obj_Desc(name).value= txt_Name obj_Desc(index).value= 1 Consider the HTML Code given below: <--!input type="textbox" name="txt_Name"--> <--!input type="radio" name="txt_Name"--> We can use the same description for both the objects and still distinguish between both of them obj_Desc(html tag).value= INPUT obj_Desc(name).value= txt_Name When I want to refer to the textbox then I will use the inside a WebEdit object and to refer to the radio button I will use the description object with the WebRadioGroup object. Browser(Browser).Page(Page).WebEdit(obj_Desc).set Test Refers to the text box Browser(Browser).Page(Page).WebRadioGroup(obj_Desc).set Test Refers to the radio button But if we use WebElement object for the description then we must define the index property because for a webelement the current description would return two objects. Getting Child Object: We can use description object to get all the objects on the page that matches that specific description. Suppose we have to check all the checkboxes present on a web page. So we will first create an object description for a checkboxe and then get all the checkboxes from the page Dim obj_ChkDesc Set obj_ChkDesc=Description.Create obj_ChkDesc(html tag).value = INPUT obj_ChkDesc(type).value = checkbox Dim allCheckboxes, singleCheckBox Set allCheckboxes = Browse(Browser).Page(Page).ChildObjects(obj_ChkDesc) For each singleCheckBox in allCheckboxes singleCheckBox.Set ON Next The above code will check all the check boxes present on the page. To get all the child objects we need to specify an object description. If you wish to use string arguments [1], same thing can be accomplished by simple scripting. Code for that would be: i=0 Do While Browse(Browser).Page(Page).WebCheckBox("html tag:=INPUT",type:=checkbox, "index:="&i).Exist Browse(Browser).Page(Page).WebCheckBox("html tag:=INPUT",type:=checkbox, "index:="&i).Set "ON" i=i+1 Loop Possible Operation on Description Objects Consider the below code for all the solutions Dim obj_ChkDesc

Set obj_ChkDesc=Description.Create obj_ChkDesc(html tag).value = INPUT obj_ChkDesc(type).value = checkbox Q: How to get the no. of description defined in a collection A: obj_ChkDesc.Count Will return 2 in our case Q: How to remove a description from the collection A: obj_ChkDesc.remove html tag would delete the html tag property from the collection Q: How do I check if property exists or not in the collection? A: The answer is that its not possible. Because whenever we try to access a property which is not defined its automatically added to the collection. The only way to determine is to check its value that is use a if statement if obj_ChkDesc(html tag).value = empty then. Q: How to browse through all the properties of a properties collection? A: Two ways 1st: For each desc in obj_ChkDesc Name=desc.Name Value=desc.Value RE = desc.regularexpression Next 2nd: For i=0 to obj_ChkDesc.count - 1 Name= obj_ChkDesc(i).Name Value= obj_ChkDesc(i).Value RE = obj_ChkDesc(i).regularexpression Next Hierarchy of test description: When using programmatic descriptions from a specific point within a test object hierarchy, you must continue to use programmatic descriptions from that point onward within the same statement. If you specify a test object by its object repository name after other objects in the hierarchy have been described using programmatic descriptions, QuickTest cannot identify the object. For example, you can use Browser(Desc1).Page(Desc1).Link(desc3), since it uses programmatic descriptions throughout the entire test object hierarchy. You can also use Browser("Index").Page(Desc1).Link(desc3), since it uses programmatic descriptions from a certain point in the description (starting from the Page object description). However, you cannot use Browser(Desc1).Page(Desc1).Link("Example1"), since it uses programmatic descriptions for the Browser and Page objects but then attempts to use an object repository name for the Link test object (QuickTest tries to locate the Link object based on its name, but cannot locate it in the repository because the parent objects were specified using programmatic descriptions).

When and Where to use Descriptive programming? Below are some of the situations when Descriptive Programming can be considered useful: 1. One place where DP can be of significant importance is when you are creating functions in an external file. You can use these function in various actions directly , eliminating the need of adding object(s) in object repository for each action[If you are using per action object repository] 2. The objects in the application are dynamic in nature and need special handling to identify the object. The best example would be of clicking a link which changes according to the user of the application, Ex. Logout <>. 3. When object repository is getting huge due to the no. of objects being added. If the size of Object repository increases too much then it decreases the performance of QTP while recognizing a object. [For QTP8.2 and below Mercury recommends that OR size should not be greater than 1.5MB]

4. When you dont want to use object repository at all. Well the first question would be why not Object repository? Consider the following scenario which would help understand why not Object repository Scenario 1: Suppose we have a web application that has not been developed yet.Now QTP for recording the script and adding the objects to repository needs the application to be up, that would mean waiting for the application to be deployed before we can start of with making QTP scripts. But if we know the descriptions of the objects that will be created then we can still start off with the script writing for testing Scenario 2: Suppose an application has 3 navigation buttons on each and every page. Let the buttons be Cancel, Back and Next. Now recording action on these buttons would add 3 objects per page in the repository. For a 10 page flow this would mean 30 objects which could have been represented just by using 3 objects. So instead of adding these 30 objects to the repository we can just write 3 descriptions for the object and use it on any page. 5. Modification to a test case is needed but the Object repository for the same is Read only or in shared mode i.e. changes may affect other scripts as well. 6. When you want to take action on similar type of object i.e. suppose we have 20 textboxes on the page and there names are in the form txt_1, txt_2, txt_3 and so on. Now adding all 20 the Object repository would not be a good programming approach.

QTP Descriptive Programming (DP) Concepts 1


by Anshoo Arora on August 10, 2009 | QTP/DP, QTP/UFT | 138 COMMENTS

Introduction
Descriptive programming has become the technique of choice for many QTP test developers. We can talk about its advantages and disadvantages all day, but here, well only discuss the concepts and come up with our own idea of what it does better, and what it doesnt :). This is going to be a very quick refresher before we move on to its everyday application by completing an end-to-end testcase.

The idea behind descriptive programming is for automation developers to instruct QTP which properties they would like to use to identify an object, instead of having QTP to choose them itself. If done correctly, this can help create robustness in scripts, ultimately requiring less maintenance-time and more development time.

Lets begin.

But wait, before we really begin, we must understand QTPs Object Spy. It is an inbuilt tool that enlists all of the test-object and runtime-object properties. These properties are different for different types for objects. For example, an image has a property called file name whereas a listbox doesnt. Instead, a listbox has a special all items property whereas the image doesnt. This discussion will be limited to the usage testobject properties to identify objects. Below are 2 snapshots of the Object Spy: p>

Object Spy Icon

Object Spy Window

Now, lets open www.Google.com and use the object spy to retrieve all properties of the search box:

Object Spy: WebEdit Properties

Notice the image above. The editbox has a HTML TAG property with its corresponding value INPUT. This means, the editbox takes some input from the user which is true because we do set some value in it! It also has a MAX LENGTH property, with a value of 2048. This means, you can enter a maximum of 2048 characters in it (the best source to see all of the Test-Object properties of objects is the QTP help itself). Below you will see an editBox which can contain a maximum of 9 characters:

Test maxLength:

You can really use all these properties to identify this editbox, but, do we really need to use all of them? No. That is the most important idea behind descriptive programming we only use what we need. Below is how we write descriptions for objects:

ObjectClassName("property:=value", "property:=value")

' ofcourse we're not limited to only 2 properties. We can write more: ObjectClassName("property:=value", "property:=value", "property:=value")

Above, ObjectClassName (in Web applications) can be Browser, Page, Frame, WebEdit, Image etc. Properties come from the left column the ObjectSpy column whereas values are in the right column. We can include as many properties as we want, but in reality, we only need to add a few to uniquely identify the object. Knowing which properties should suffice to uniquely identify can object will come from experience and practice. Below is a description I created for this editbox (WebEdit):

'ObjectClassName( "property1:=value1", "property2:=value2" ) WebEdit( "name:=q", "html tag:=INPUT" )

I already mentioned the HTML TAG and its value INPUT above. Weve also added a new property/value here: name:=q. Is this enough to uniquely identify the object? Yes. But is it enough to make our script work? No, sadly its not.. and that is because, we havent yet created descriptions for its parent objects: Browser & Page. Below are the snapshots of the spied browser and page objects:

Object Spy: Browser Properties

Object Spy: Page Properties

BROWSER DESCRIPTION

'ObjectClassName( "property1:=value1" ) Browser( "title:=Google" )

PAGE DESCRIPTION

Page( "title:=Google" )

Now, we will connect all these descriptions and form a hierarchical tree:

Browser("title:=Google").Page("title:=Google").WebEdit("name:=q","html tag:=INPUT")

You might wonder why I have omitted the WebTable below the Page and above the WebEdit object. In practice, we can also skip the Page object to identify the WebEdit. But, why did I skip the WebTable after all!? When you experiment more with DP, you will discover that some objects are embedded in many WebTables, and it will become cumbersome if we were to include all WebTables in the hierarchy to get to the object of interest (thanks to the person who thought that will be a terrible idea!). Example of the previously mentioned scenario:

Object Spy: Multiple WebTables

To complete the statement above, we will add an event. In QTP, events can be described as actions on target objects. For example, a WebEdit has a Set event. we use the Set method of a WebEdit to set a value:

Browser("title:=Google").Page("title:=Google").WebEdit("name:=q","html tag:=INPUT").Set "DP"

Set is a QTP event to put in a value in the edit box. Different objects have different events. For example: an Image has a Click event associated with it.

This, we did without using Object Repository. The same concept applies to all objects regardless of what your environment is. We perform actions on child objects by accessing their object hierarchies. Lets complete the above example by searching for our keywords (use the spy again on the search button):

Browser("title:=Google").Page("title:=Google").WebEdit("name:=q", "html tag:=INPUT").Set "DP" Browser("title:=Google").Page("title:=Google").WebButton("name:=Google Search").Click

This is how the same code will look like if we had recorded this process:

Browser("Google").Page("Google").WebEdit("q").Set "DP is great" Browser("Google").Page("Google").WebButton("Google Search").Click

These properties are now stored in QTPs Object Repository (OR). There is another way we can create object descriptions, which is done by setting a reference:

' Creating Browser description ' "title:=Google" Set oGoogBrowser = Description.Create oGoogBrowser( "title" ).value = "Google"

' Creating Page description ' "title:=Google" Set oGoogPage = Description.Create oGoogPage( "title" ).Value = "Google"

'* Creating WebEdit description ' "html tag:=INPUt", "name:=q" Set oGoogWebEdit = Description.Create oGoogWebEdit( "html tag" ).Value = "INPUT" oGoogWebEdit( "name" ).Value = "q"

Once we do the above, we can use this descriptions in our script:

Browser(oGoogBrowser).Page(oGoogPage).WebEdit(oGoogWebEdit).Set "DP is great"

The only time I use this technique is to retrive object collections through ChildObjects (we will discuss this in the coming tutorials).

Lets do another example. Again, we will use Google, but instead of setting a value, we will click an object. You can choose any Link on the page; I chose the link Images:

Object Spy: Google Images Link

'ClassName("property:=value").ClassName("propert1:=value").ClassName("property:=value").Event Browser("title:=Google").Page("title:=Google").Link("innertext:=Images", "html tag:=A").Click

This time, instead of Set we used Click. Following is a list of events we perform on Web objects:

OBJECT

EVENT

Image WebButton WebCheckBox WebEdit WebElement WebList WebRadioGroup

Click Click Set Set Click Select Select

QTP Descriptive Programming (DP) Concepts 2 (Regular Expressions)


by Anshoo Arora on August 10, 2009 | QTP/DP, QTP/UFT | 74 COMMENTS

A wildcard character can be used to substitute for any other character or characters in a string.1 This means, we can use a wildcard to make our descriptions more generic. For example, if the property file name of an Image is getAllAttributes.JPG, we can use a wildcard several ways:
' Only using the first 2 words: getAll Browser( "title:=MyTitle" ).Page( "title:=MyTitle" ).Image( "file name:=getAll.*" ).Click ' Using 1 word (Attributes) with the extension (JPG) Browser( "title:=MyTitle" ).Page( "title:=MyTitle" ).Image( "file name:=.*Attributes.*JPG" ).Click

Lets put this technique into practice. Lets use Mercury Tours for this test. Lets try to identify the banner image (banner2.gif) having the following text embed: one cool summer ARUBA.

This image is the property of http://newtours.demoaut.com (HP/Mercury)

Browser("title:=Welcome: Mercury Tours").Page("title:=Welcome: Mercury Tours")_ .Image("file name:=banner2.gif").Highlight

Browser("title:=Welcome: Mercury Tours").Page("title:=Welcome: Mercury Tours").Image("file name:=banner2.*").Highlight

Browser("title:=Welcome: Mercury Tours").Page("title:=Welcome: Mercury Tours").Image("file name:=banner.*").Highlight

Browser("title:=Welcome: Mercury Tours").Page("title:=Welcome: Mercury Tours").Image("file name:=ban.*gif").Highlight

Browser("title:=Welcome: Mercury Tours").Page("title:=Welcome: Mercury Tours").Image("file name:=ban.*f").Highlight

Ofcourse, there are more ways to identify the banner image, but Ive only used the above 5. Similarly, we can use this wildcard character for the Browser and Page objects:

' Without wildcard(s): 0.20 seconds Browser("title:=Welcome: Mercury Tours").Page("title:=Welcome: Mercury Tours").Image("file name:=banner2.gif").Click

' With wildcard(s): 0.30 seconds Browser("title:=Welcome.*").Page("title:=.*Mercury Tours").Image("file name:=banner2.gif").Highlight

' 0.28 seconds Browser("title:=Welcome:.*").Page("title:=Welcome.*").Image("file name:=banner2.*").Highlight

' 0.56 seconds Browser("title:=.*Mercury Tours").Page("title:=.*: Mercury.*").Image("file name:=banner.*").Highlight

' 0.61 seconds Browser("title:=.*Mercury Tour.*").Page("title:=Welcome:.*").Image("file name:=ban.*gif").Highlight

' 0.51 seconds Browser("title:=.*: Mercury.*").Page("title:=.*Mercury Tour.*").Image("file name:=ban.*f").Highlight

You might notice a little drop in performance for some of the above statements. This is quite obvious though. Using a real world example:

Scenario 1

If you were asked to deliver a letter to John and you had the following piece of information provided: Building 184, Floor 5, Room 120, Desk 9. You would know that you first have to find Building A, then take an elevator to the 5th floor, find Room 120, and once youre inside room 120, John sits on Desk # 9. This is quite straight-forward and ofcourse youll be able to quickly find John.

Scenario 2
In another scenario, if you were asked to deliver a letter to John who is in Building 184 and on the 5th floor, how would you find John? You would have to go to each room and ask for John, and make sure it is the correct John before delivering the letter to him. This might take longer.

This is roughly what happens in our scripts. As our descriptions get more and more generic, the time it takes to identify the object increases. Therefore, even though wildcard characters can simplify our work, we should be a little careful how we use them.

Regular-Expressions.Info is a good source to learn regular-expressions. We will now do the exact same test we did about with Banner2.gif, but this time using some more regex style characters.
' Using the first few characters of the title and the first few characters of the image Browser("title:=Welc\w+\D+\w+").Page("title:=Welc\w+\D+\w+").Image("file name:=ban\w+\d+\.\w+").Highlight

' Using the last few characters of the title with first and last characters of the image Browser("title:=\w+\D+\w+ours").Page("title:=\w+\D+\w+ours").Image("file name:=b\w+2\.gif").Highlight

' Same as above for Browser and Page, but '...' for image Browser("title:=\w+\D+\w+ours").Page("title:=\w+\D+\w+ours").Image("file name:=b\w+2\....").Highlight

' Same as above, but replaced 'b' with a '.' Browser("title:=\w+\D+\w+ours").Page("title:=\w+\D+\w+ours").Image("file name:=.\w+2\....").Highlight

In the proceeding article we will cover Ordinal Identifiers and also see how to create a simple test module for a login process.

QTP Descriptive Programming (DP) Concepts 3 (Ordinal Identifiers)


by Anshoo Arora on August 10, 2009 | QTP/DP, QTP/UFT | 75 COMMENTS

This is the third article in the Descriptive Programming series, and will outline the concepts of Ordinal Identifiers used in QTP. We will also create a simple test module (step by step) for a login process using only Descriptive Programming (DP).

Ordinal Identifiers What are they?

Let me quote QTP Reference here:

An ordinal identifier assigns a numerical value to a test object that indicates its order or location relative to other objects with an otherwise identical description (objects that have the same values for all properties). This ordered value provides a backup mechanism that enables QuickTest to create a unique description to recognize an object when the defined properties are not sufficient to do so.

Lets break the above definition from Mercury/HP into several parts to clarify the concept.

An ordinal identifier assigns a numerical value to a test object

From the quote above, we can conclude that an ordinal identifier is a numerical entity. In other words, its simply a number that is assigned to a test object.

that indicates its order or location relative to other objects with an otherwise identical description (objects that have the same values for all properties)

This means, an Ordinal Identifier works quite differently in relation to the properties we learned in the 1st part of this series. This identifier, or a property if you will, works according to the order or location of test objects. Objects order and location are unique characteristics. For example, in a coordinate system, generally only a single object exists on a given x,y coordinate. Thus, an ordinal identifier will always be unique. Index defines the order, and location defines location. This ordered value provides a backup mechanism that enables QuickTest to create a unique description to recognize an object when the defined properties are not sufficient to do so.

The quote above is a good way to conclude this concept of Ordinal Identifiers in QTP. Since it is always unique for an object, it can become extremely useful including these with objects mandatory and assisstive properties to prevent falling into object recognition problems. The 3 types of ordinal identifiers are: Location, Index and CreationTime (browser only).

Location Ordinal Identifier


Lets use an example to understand how the Location Identifier works. Consider the 4 WebEdits below:

Text Box 1: Text Box 3:

Text Box 2: Text Box 4:

All the edits above have exactly the same properties. This property works vertically, from top to bottom, and left to right. Thus, Text Box 1 will have a location value of 0, Text Box 3 will have 1, Text Box 2 will have 2, and Text Box 4 will have 3. Note that VBScript is zero based, so the location property would start at 0. This can be verified by running the following statements:
'Text Box 1 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest","location:=0").Set "1"

'Text Box 3 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest","location:=1").Set "2"

'Text Box 2 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest","location:=2").Set "3"

'Text Box 4 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest","location:=3").Set "4"

Text Box 1: location=0 Text Box 2: location=2 Text Box 3: location=1 Text Box 4: location=3
Index Ordinal Identifier
Index is quite similar to location, but it works pertaining to appearance of objects in the source code1. An object appearing prior in the source code will have a smaller Index value as compared to another object that comes later in the source. Thus, for the same group of edit boxes above: Text Box 1 will have an index of 0, Text Box 2 will have 1, Text Box 3 will have 2 and Text Box 4 will have 3. Lets test our statements:
1

Credits go to Harish for finding this error.

'Text Box 1 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest", "index:=0").Set "1"

'Text Box 2 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest", "index:=1").Set "2"

'Text Box 3 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest", "index:=2").Set "3"

'Text Box 4 Browser("title:=.*Descriptive.*").Page("micclass:=Page").WebEdit("name:=dpTest", "index:=3").Set "4"

Text Box 1: index=0 Text Box 2: index=1 Text Box 3: index=2 Text Box 4: index=3

That was quite easy, wasnt it? Now, lets move on to CreationTime, which is an ordinal identifier strictly reserved for the browser object.

CreationTime Ordinal Identifier


Again, lets use the description given by HP/Mercury in QTPs helpfile:

If there are several open browsers, the one with the lowest CreationTime is the first one that was opened and the one with the highest CreationTime is the last one that was opened.

That means, the first browser you open will have a creationtime of 0. The second browser will have a creationtime of 1. The third browser will have a creationtime of 2 and so on.

SystemUtil.Run "iexplore.exe", "http://www.HP.com" SystemUtil.Run "iexplore.exe", "http://www.AdvancedQTP.com" SystemUtil.Run "iexplore.exe", "http://www.LinkedIn.com"

'CreationTime 0 'CreationTime 1 'CreationTime 2

Browser( "creationtime:=" ).Highlight Browser( "creationtime:=1" ).Highlight Browser( "creationtime:=2" ).Highlight

'Highlight HP.com 'Highlight AdvancedQTP.com 'Highlight LinkedIn.com

When you run the above code in QTP, you will find that the first browser QTP highlights on is HP.com, the second is AdvancedQTP.com and the third is LinkedIn.com. Even this is quite simple, isnt it?

As promised, we must create a simple login process using the concepts we have learned so far in the next article.

QTP Descriptive Programming (DP) 4 (Creating a Test Script)


by Anshoo Arora on August 10, 2009 | QTP/DP, QTP/UFT | 117 COMMENTS

This is the last article in our Descriptive Programming series and will cover a simple login process using 100% DP. I have purposely created the example to be very high-level to make sure its quit easy to understand. However, if you feel more examples on this concept will help, Ill be more than happy to create a Part V of this series with only real-world examples of DP in action.

We will use the HP/Mercury Demo Website for this example. Following is the process I am going to follow to complete this process. In your application however, you can use the process that best suits your needs, but for the purposes of this lesson, I will keep it quite basic:

1. 2. 3. 4. 5.

Launch Browser. Check whether the correct browser opened. Ensure the userName, password edits and the Sign-In button exist. Set the userName and password and Click Sign-In. Make sure the browser navigated to the correct page.

Step 1: Launch Browser


'We will use SystemUtil.Run to launch our target browser SystemUtil.Run "iexplore.exe", "http://newtours.demoaut.com/"

Step 2: Checking if the correct browser opened


The 2 new concepts in this step are:

1.

Reporter Object: This object is used to send individual reports to the test results. In other words, when the test ends, you can see the reported events in your Test results.

2.

ExitTest: A utility statement available to QTP that enables it to complete exit a Test. In other words, when this statement executes, the test execution ends.

If Browser( "title:=Welcome: Mercury Tours" ).Exist( 15 ) Then Reporter.ReportEvent micPass, "Step 1- Launch", "Correct browser was launched."

Else Reporter.ReportEvent micFail, "Step 1- Launch", "Browser failed to launch." ExitTest End If

Step 3: Ensure the userName, password edits and the Sign-In button exist.
'Notice the use of the wildcard character below If Browser("title:=Welcome:.*").Page("title:=Welcome.*").WebEdit("name:=userName").Exist(0) Then 'set username If Browser("title:=Welcome:.*").Page("title:=Welcome.*").WebEdit("name:=password").Exist(0) Then 'set password If Browser("title:=Welcome:.*").Page("title:=Welcome.*").Image("name:=login" ).Exist(0) Then 'click button Else 'report that Sign-In button was not found End If Else 'report that the password edit was not found End If Else 'report that the userName edit was not found End If

Step 4: Set the userName and password and Click Sign-In.


The following will complete the snippet above:

'Notice the use of the wildcard character below With Browser("title:=Welcome:.*").Page("title:=Welcome.*") If .WebEdit("name:=userName").Exist(0) Then .WebEdit("name:=userName").Set "test" If .WebEdit("name:=password").Exist(0) Then .WebEdit("name:=password").Set "test" If .Image("name:=login" ).Exist(0) Then .Image("name:=login" ).Click Else Reporter.ReportEvent micFail, "Sign-In Button Error", "Button not found." End If

Else Reporter.ReportEvent micFail, "Password Edit Error", "EditBox not found." End If Else Reporter.ReportEvent micFail, "UserName Edit Error", "EditBox not found." End If End With

Step 5: Make sure the browser navigated to the correct page


'Synchronize with a browser Browser( "title:=.*" ).Sync

'Wait 1 second for browser with "Find a Flight" title to exist If Browser( "title:=Find a Flight.*" ).Exist( 1 ) Then Reporter.ReportEvent micPass, "Login", "Login successful" Else Reporter.ReportEvent micFail, "Login", "Login failed" End If

PUTTING IT ALL TOGETHER

'We will use SystemUtil.Run to launch our target browser SystemUtil.Run "iexplore.exe", "http://newtours.demoaut.com/"

If Browser( "title:=Welcome: Mercury Tours" ).Exist( 15 ) Then Reporter.ReportEvent micPass, "Step 1- Launch", "Correct browser was launched." Else Reporter.ReportEvent micFail, "Step 1- Launch", "Browser failed to launch." ExitTest End If

'Notice the use of the wildcard character below With Browser("title:=Welcome:.*").Page("title:=Welcome.*") If .WebEdit("name:=userName").Exist(0) Then .WebEdit("name:=userName").Set "test" If .WebEdit("name:=password").Exist(0) Then .WebEdit("name:=password").Set "test" If .Image("name:=login").Exist(0) Then

.Image("name:=login").Click Else Reporter.ReportEvent micFail, "Sign-In Button Error", "Button not found." End If Else Reporter.ReportEvent micFail, "Password Edit Error", "EditBox not found." End If Else Reporter.ReportEvent micFail, "UserName Edit Error", "EditBox not found." End If End With

Browser( "title:=.*Mercury.*" ).Sync

If Browser( "title:=Find a Flight.*" ).Exist( 1 ) Then Reporter.ReportEvent micPass, "Login", "Login successful" Else Reporter.ReportEvent micFail, "Login", "Login failed" End If

If you have any doubt in the content above, please feel free to post a comment about it. I hope this article helps understand further the principles of Descriptive Programming and using it in your everyday work.

You might also like