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, we’ll only discuss the concepts and come up with our own idea of what it does better, and what it doesn’t :). 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.
But wait, before we really begin, we must understand QTP’s 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 doesn’t. Instead, a listbox has a special ‘all items’ property whereas the image doesn’t. This discussion will be limited to the usage test-object properties to identify objects. Below are 2 snapshots of the Object Spy:
Now, let’s open www.Google.com and use the object spy to retrieve all properties of the search box:
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:
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. We’ve 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 haven’t yet created descriptions for its parent objects: Browser & Page. Below are the snapshots of the spied browser and page objects:
'ObjectClassName( "property1:=value1" ) Browser( "title:=Google" )
Page( "title:=Google" )
Now, we will connect all these descriptions and form a hierarchical tree:
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:
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. Let’s 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 QTP’s 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).
Let’s 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':
'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: