DP from a personal point of view
Now that we've covered some of the basic issues regarding Descriptive Programming, I can elaborate further, on a more personal note. I've picked up some coding habits during my days, and some of them are DP related. Habits are arbitrary by definition, so there may indeed be better ways of doing things out there. However, I see no harm in pointing out a thing or two:
I don't trust regular expressions in DP
When we create a static description object, we can define the identification values by using Regular Expressions:
Dim oDesc
Set oDesc = Description.Create
oDesc("property1").Value = "RegExPattern"
oDesc("property1").RegularExpression = True
For example:
oDesc("text").Value = ".*Middle of text.*"
oDesc("property1").RegularExpression = True
I never do this, mainly because most of the time, the identification criteria is much too complex, requires accessing run-time properties, etc. So, instead of filtering the objects this soon, I use a very basic identification criteria (e.g. the object time beign Combobox / Checkbox / whatever), which results in a large object collection (since many objects comply with the identification criteria). Sometimes I would even leave the description object blank, and get all the objects in the window/application.
Once I have my collection, I can run through it, and easily find any object that I'm interested in – even if my criteria are very complex. For example, say I want to find a checkbox with a given Tooltip:
Dim oDesc, oChildren
Dim i
Set oDesc = Description.Create
oDesc("micclass").Value = "VbCheckbox"
Set oChildren = VbWindow("Main").ChildObjects(oDesc)
For I = 0 to oChildren.Count -1
If oChildren(i).GetROProperty("ToolTipText") = "WantedToolTip" Then
End If
Next
Since I write my own identification code (i.e. the IF conditions), I enjoy total freedom and flexibility, and I can write a much more tidy and readable code (I can unite many .ChildObjects commands by doing one that receives all the objects, and separate the different cases by Select Case switch).
I create objects collections even without the .ChildObjects command
As you might have guessed by now, I use the .ChildObjects command a LOT. As a result, many of my functions are built to receive and deal with objects collections, and not straight on, specific objects. This means that in case I occasionally use "regular" objects, I either have to write duplicate code (to deal with objects, as well as collections) , or to find a way to transform objects into collections.
Well, since duplicate code is evil manifested via digital form, I tend to use the second option. Here's how I artificially create a collection, and add an existing object to it:
Dim oObjectCollection
Set oObjectCollection = CreateObject("Scripting.Dictionary")
oObjectCollection.Add 0, VbWindow("Main")
About the last line: what happens is we add the object VBWindow("Main") to the collection, and we set its identifier to 0 (by which it can be "pulled out" of the collection). Identifiers can actually be strings (e.g. name, phone number, internet address etc.), but in order to be compatible with ChildObjects generated collections, I use a zero-based numeric identifier. The syntax for using an object within the collection remains the same as with .ChildObjects collections:
oObjectCollection(0).Click
A quick note regarding Scripting.Dictionary objects – these are extremely useful in a variety of situations. I strongly recommend getting familiar with them as soon as possible (see QTP help – under "Dictionary Object").
I prefer full DP over OR run-time change
Some QTP programmers like to record objects to the native OR, and then change their properties during run-time using the SetTOProperty command (more on that command in the future). In my opinion, this results in scattered object-identification logic, de-encapsulation, it causes confusion, and turns debug into a living hell.
If I'm going to change an object's OR description on a regular basis, I remove it from the OR, and use DP instead.
I ALWAYS use the index property
When adding the index property to a DP statement, we can protect ourselves from situations in which two or more objects match the same description. The down side is, that it might be important to know when these situations actually occur. Having said that, I prefer a stable script over this information. In QTP 8.2, the index property would work ONLY when there was more than one object matching the description, but in later versions (9+), this issue was resolved, so there's really no reason not to use the Index property. For example :
VBWindow("title:=Example", "index:=0").VBCheckBox("visible:=true", _
"index:=0").Set "ON"
