Descriptive programming in QTP :
Descriptive programming in QTP :
When using Descriptive programming, we’re bypassing the native object repository mechanism, which may have many advantages, but is extremely not flexible. We’ll examine situations in which the OR’s advantages are outweighed by the DP’s flexibility.
In order to fully grasp how DP actually works, it’s best to first understand how QTP’s native OR works. The native OR is not some complex and deep mechanism, but rather a simple way of keeping groups of properties and values. To clarify: Whenever we add a certain window to the OR, QTP gathers the window’s properties (e.g. – Height=”400?, Title=”New Entity”, vbName=”NewEntityID”), and stores them as a group of property-value pairs. When QTP runs the script, it compares these properties and values to the “physical” objects, and finds (or fails to find) the object which they describe. Nothing mystical about it.
In DP, we’re “manually” specifying the properties and values by which the relevant object will be identified. This way QTP won’t search for the properties data in the OR, but will take it from the DP statement. This can be done in a fast, ad-hoc way, in the very line of the command we want to execute:
The syntax is: Class(PROPERTIESSTRINGS).Command, where PROPERTIESSTRINGS specifies the properties and values for the object’s identification. For example:
We can even create an object hierarchy:
Of course “VBWindow” class is just an example for DP with VB objects. DP can be done with SWFWindow, Browser, WinComboBox etc.
The only difference between using DP to using the native QTP OR, is in the content within the class’s brackets (in this example: VBWindow()). When using the native OR, we’ll put the logical name of the object as defined in the OR. When using DP, we’ll put strings describing the properties and values the object will be identified by (structured as “property:=value”).
This syntax has the benefit of being shot and quick, but may cause problems if we’ll use the object again somewhere else. In this case we’ll have to rewrite the all the description strings, making the code less readable, and harder to maintain (i.e., if one of the properties were to change, we’ll be forced to make several repairs in different places throughout the code). Luckily, DP allows us to define a static descriptive object, and set its properties once. This way, the script simply refers to the descriptive object.
Well, you might ask yourself why we even bother. QTP’s native OR does all these things, is tidier, and up to QTP 9, was the only way to enjoy the benefits of code auto-complete. Well, in some sense, you’re right – sometimes, the best way to go is to use the OR, straight up. However, in some cases, DP is preferable by far, and sometimes even the only way to go:
Easy-breezy coding: if we’re only going to use an object once or twice, there’s no need to use the slow, complex OR, when you can just immediately write the ID string as part of the command. Moreover, with DP you can copy code-snippets between scripts, without having to worry about references to undefined object in the new script.
Inherent dealing with double objects: in case the identification properties and values match more than one object, QTP will through an “object’s description matches more than one of the objects currently displayed in your application” error. If we’re using the native OR, there no easy way to deal with the situation (we could use a complex Recovery Scenario, but it gets very ugly, very soon). However, DP easily deals with double objects by using the index property. We can add “index:=X” to the description strings (when X is a zero-based counter), and QTP will point to object #X.
Object reference in external functions: when using external functions, you can never count on the relevant object being defined in the calling action’s OR. And even if the object is defined there, its logical name might be different, so really, DP remains the only option.
Objects that change hierarchies: sometime an object will appear under a different parent each time (e.g. – a pop-up which appears under the initiating sub-window). In some applications, the only way to work with such objects is with DP.
Working with a collection of objects: other reasons aside, this is the “Killer Feature” of DP. It makes DP a must for every QTP programmer, and it’s hard to overstate its importance and inherent possibilities. According to this concept, instead of working with a single object at a time, we can gather all the objects which answer to our identification properties, and work with them as a collection, serially.
This will be clarified via an example: we’re dealing with an unknown number of checkboxes. We don’t know (and don’t care) how they’re called, or where they are on the screen – we just need to mark all of them as checked. If we were to do this “the old way”, we would have to keep track of each checkbox’s properties, and write separate commands that identify each of them, and marks them. With the new objects-collection method, we can ask for all the checkboxes in the screen, loop through them, and mark all of them with a single, easily maintainable command.
This method represents a major improvement, since we’ve severely reduced our dependence in the application. If the number of checkboxes, their locations, or their names were to change, our code will need zero-maintenance to keep on working. Moreover, in some situations, this method is really the only possible way to go.
This method is implemented with the .ChildObjects command. It receives a DP descriptive object, and returns a collection of the objects that answer to the description. The description can have 0 properties, in which case all the objects will be returned.
As you may have noticed, the .ChildObjects command must be executed on a top-level window. This means that you can’t get a collection of the top-level windows of an app, only a collection of child-objects In a certain top-level window. This was true until QTP 9, which introduced the Desktop utility object. This allows us to execute Desktop.ChildObjects(oDesc), which returns a collection of top-level windows, so all is well.
- It’s a white box
- Compatible with different QTP versions
- Code portability is high
- Easy to mass update
- Lower Code Readability and requires more comments, like “what object is accessed”
- Potentially slower to create
- There is no UI to Highlight the object
When to Use DP?
Descriptive programming is not a replacement of OR but its mainly used when we have to deal with dynamic objects which change their properties during the runtime and if we use OR then these would fail. We can then create a description of an object at the runtime and then use it.
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 don’t 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. 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.
For Example: During Run Time u might not know how many Checkbox appears in a web Page you have to select all the Checkbox that appears. Then comes the Use of Descriptive Programming where you describe the Test object Checkbox with certain Properties and Check all the Checkbox that appeared during Run Time irrespective of the number of Checkbox appeared.
Another Example is: Suppose you are testing Yahoo Website. After you login, it lists all the mails present in your inbox with a checkbox for each mail. Using this checkbox you can select a mail for deletion or for moving it etc.
But when you design your test, you do not know how many check boxes (mails) will be displayed on the page, and you cannot, of course, know the exact object description of each check box. In this situation, you can use a programmatic description to instruct QuickTest to perform a Set “ON” method for all objects that fit the description:
HTML TAG = input, TYPE = check box
1) Following script refers to the descriptive object
Set objEdit = Description.Create
objEdit(“type”).Value = “text”
objEdit(“name”).Value = “q”
objEdit(“htmltag”).Value = “INPUT”
Set objEdit = Nothing
2)Following example demonstrates the .ChildObjects command syntax, as well as a pretty standard way to utilize the returned collection:
oDesc = Description.Create
oDesc(“micclass”).Value = “VbCheckBox”
‘—-We could’ve left the oDesc object blank, To get all objects—-’
Set oChildren = VBWindow(“Main”).ChildObjects(oDesc)
‘—-Now oChildren holds the checkboxs’ collection—-’
‘—-Run through the collection—-’
For I = 0 to oChildren.Count-1‘—-Set the specific Checkbox to “ON”—-’
3)Another Method :
If objEdit.Exist Then