Descriptive Programming in QTP/UFT: Dynamic & Static
โก Smart Summary
Descriptive programming lets a QTP or UFT One statement carry the object description itself, as property value pairs or as a Description object, so a step runs even when the object was never stored in the Object Repository.
What is Descriptive Programming?
Descriptive programming is used to execute operations on an Object in the AUT whose definition is not stored in the Object Repository. Using this mechanism, you can bypass identification from the Object Repository and supply the Object Description in the statement itself.
An object name is simply used to map an object in a script with its description in an object repository. This means that if you change the object name in both your script and the object repository, the script should still run. Watch the following video on this concept
Click here if the video is not accessible
Video Highlights
- Delete the Object Description of the Agent Name WinEdit box from the Object Repository. If you run the test again it will fail, since it cannot recognize the object. Let’s examine the reason why the script is failing
- During Run Time, UFT One identifies the operation that is performed on the WinEdit box, and the Object Description in the Object Repository is stored as Agent Name. It uses this name to track the object in the object repository. For a parent, you cannot have two child objects with the same name, so QTP uniquely maps the object in the repository. It then uses the stored description in the Object Repository, replaces the name with the description, and uses the resulting statement to identify the object in the application under test
- Since in our case we had deleted this object description altogether, the script fails
- But what if, instead of QTP replacing the object description, you as a tester directly specify the object descriptions in your script? This is nothing but “Descriptive Programming”
That single change of responsibility is what the two forms below implement, and each form suits a different kind of script.
Types of Descriptive Programming
You can use Descriptive programming in two ways
- Static
- Dynamic
Static Descriptive Programming
In Static Method, for object identification, you specify an object’s property in the following format
property:=values,
This format is called a property value pair and is enclosed in inverted commas. Written out in full, a static statement looks like this:
TestObject("PropertyName1:=PropertyValue1", "PropertyName2:=PropertyValue2").Method
If your object uses multiple descriptions for identification, you can specify those using commas
So in our case, the description for Agent Name becomes
"nativeclass:=Edit", "attached text:=Agent Name:"
Static descriptions are read at the point where the statement runs, which makes them ideal for one-off steps and for quick fixes to a script you do not want to re-record.
Dynamic Descriptive Programming
The second method of doing the same action is using Dynamic Descriptive programming
In case your script uses the descriptive programming object candidate multiple times, it will be very tiresome to specify all the property value pairs for each statement
In such cases, you can make use of the Description Class provided by QTP
The syntax for creating a description object is
Set MyDescription = Description.Create() MyDescription("property").Value = "property-value"
This is the Dynamic Method
Filling that object with the Agent Name properties used above gives a complete, reusable description:
Dim oDesc Set oDesc = Description.Create() oDesc("nativeclass").Value = "Edit" oDesc("attached text").Value = "Agent Name:"
The variable oDesc can now be passed to any statement that needs that object, so one edit updates every step that uses it.
Static vs Dynamic Descriptive Programming: When to Use Each
Both forms produce the same run-time description, so the choice is about maintenance rather than capability.
| Criteria | Static (inline) | Dynamic (Description object) |
|---|---|---|
| How the description is written | Property value pairs typed inside the test object call | Properties added to an object created with Description.Create() |
| Reuse | Repeated in every statement that needs the object | Stored in one variable and passed wherever it is needed |
| Readability | Short statements stay readable; long ones become unwieldy | Extra setup lines, but the statement itself stays short |
| Runtime changes | Values are fixed unless concatenated from variables | Property values can be reassigned before each use |
| Works with ChildObjects | No, the filter argument must be a Description object | Yes, this is the required form |
| Best suited to | One or two steps on an object that is not in the repository | Objects used repeatedly, or collections retrieved at run time |
Why Use Descriptive Programming?
The transcript below accompanies the video walkthrough of a real scenario where the object count cannot be known in advance.
Video Transcript
- The million dollar question is why to use DP when the Object Identification process is handled by QTP
- Suppose you are assigned to test a job portal. You enter a search query into the portal, and your test expects you to select all available jobs and click Apply Job
- But the number of jobs reflected will depend on the search query and the jobs available at the time of script execution, and there is no way to predict in advance the number of jobs that would be reflected
- In such cases, you can use descriptive programming. Even though you do not know the number and names of the checkboxes, you do know the class for the objects as “WebCheckBox”
- You can use the ChildObjects method to return objects belonging to a particular parent
- A line of code like –
Set allObjects = Browser("Jobs").Page("QTP").ChildObjects()
will return all child objects for this page.
- But we want only WebCheckBox objects. To do so we can create a filter object and set its property to the web check box class, then pass this filter as an argument to the ChildObjects method
- In this case, only the checkboxes are returned.
- Next, you can write code like this, which accesses the entire collection of checkboxes starting from zero and sets all checkboxes ON.
- Next, you can click the apply button to complete the test
- You can also use Descriptive Programming to run objects which are difficult to record like Auto-Hide Panels, Objects with changing hierarchies, Nested Inner Objects, Sub-menus.
- You can also do advanced string manipulations using descriptive programming
- In conjunction with the index property, descriptive programming could be very useful in identifying difficult objects.
- If you use programmatic description for an object in an object hierarchy, you will need to use descriptive programming for succeeding child objects
- For example, if descriptive programming was used for the Page object but the succeeding child WinEdit object came from the Object Repository, the statement is incorrect
- On the contrary, when descriptive programming is used for both the Page and the WinEdit objects, the statement is correct
Written out, the filter and the loop described in the transcript look like this:
Dim oFilter, allCheckBoxes, i Set oFilter = Description.Create() oFilter("micclass").Value = "WebCheckBox" Set allCheckBoxes = Browser("Jobs").Page("QTP").ChildObjects(oFilter) For i = 0 To allCheckBoxes.Count - 1 allCheckBoxes(i).Set "ON" Next
The collection is zero based, which is why the loop stops at Count – 1. Because the filter is evaluated when the line runs, the same code works whether the search returns three jobs or thirty.
Regular Expressions, Ordinal Identifiers and Common Pitfalls
Descriptive programming behaves in two ways that surprise most people the first time a statement fails for no visible reason.
1) Every property value is treated as a regular expression. A caption such as Total (USD) therefore fails to match, because the parentheses are regular expression syntax. Escape them with a backslash, or switch regular expression evaluation off for that property on a Description object:
Set oDesc = Description.Create() oDesc("name").Value = "Total (USD)" oDesc("name").RegularExpression = False
2) Ordinal identifiers break ties. When a description still matches more than one object, add index, location or creationtime as an extra property. The index count starts at zero:
WebEdit("name:=userName", "html tag:=INPUT", "index:=0").Set "guru99" WebEdit("name:=userName", "html tag:=INPUT", "index:=1").Set "guru99"
Three further pitfalls are worth checking before you start debugging the application:
- Use micclass, not the label Class Name shown in Object Spy. The display name is not a valid property in a description.
- Property names are case insensitive but must be spelled exactly as the technology reports them, including the space in attached text and html tag.
- Descriptive programming bypasses the repository; it does not improve object recognition. If the correct add-in is not loaded, no description will make the object identifiable.
