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.

  • ๐Ÿ”˜ Bypasses the repository: The description travels inside the statement, so no object name has to be looked up at run time.
  • โ˜‘๏ธ Static form: Property value pairs written inline as “property:=value”, separated by commas inside the test object call.
  • โœ… Dynamic form: Description.Create builds a reusable properties collection that many statements can share.
  • ๐Ÿงช Built for unpredictable objects: Auto-hide panels, changing hierarchies, nested inner objects and result sets of unknown size.
  • ๐Ÿ› ๏ธ ChildObjects pairs with it: A Description object used as a filter returns only the matching children of a parent.
  • ๐Ÿ“Œ Two rules to remember: Every property value is treated as a regular expression, and once you describe a parent you must describe its children too.

Static and dynamic descriptive programming statements in QTP and UFT One

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

  1. Static
  2. 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.

FAQs

Point Object Spy at the control and read its identification properties, or call GetROProperty at run time. Copy the names exactly as listed, remembering that Object Spy displays micclass under the label Class Name.

Not usually. A repository lookup resolves a stored description once, while a described statement is evaluated every time the line runs. The benefit of descriptive programming is flexibility on unpredictable objects, not raw speed.

Build the Description object inside a reusable function and keep that function in a VBScript function library associated with the test. Every action that loads the library can then call it, so one edit updates all callers.

AI-assisted identification matches controls by visual appearance and nearby label text instead of fixed properties, which removes some hand-written descriptions. Descriptions are still needed where objects are counted or filtered at run time.

Copilot can scaffold the loops, Description.Create calls and reporting around a description, but it cannot see your application. Every property name and value it suggests has to be confirmed against the real control before the statement is trusted.

Rarely. A shared object repository keeps descriptions in one editable place and keeps scripts readable. Most teams keep stable screens in the repository and reach for descriptions only where objects are dynamic.

Reduce it to a single property, then add the others back one at a time. Checking the object count with a ChildObjects filter shows whether the description matches nothing or matches several objects ambiguously.

Yes. It works for any technology whose add-in is loaded, including standard Windows, web, .NET, Java and terminal emulator objects. Only the property names differ, since each add-in reports its own identification properties.

Summarize this post with: