Sep
26
2008
--

DP Part 1 - Overview

Introduction

This document demonstrates the usage of Descriptive programming in QTP 8.20. It also discusses situations where Descriptive programming can be used. Using Descriptive Programming automation scripts can be created even if the application has not been developed.

Descriptive Programming

Whenever QTP records any action on any object of an application, it adds some description on how to recognize that object to a repository of objects called object repository. QTP cannot take action on an object until unless its object description is in the Object Repository. But descriptive programming provides a way to perform action on objects which are not in Object repository

Object Identification:

To identify an object during the play back of the scripts QTP stores some properties which helps QTP to uniquely identify the object on a page. Below screen shots shows an example Object repository:

Sample object repository

Sample object repository

Now to recognize a radio button on a page QTP had added 2 properties the name of the radio button and the html tag for it. The name the left tree view is the logical name given by QTP for the object. This can be changed as per the convenience of the person writing the test case. QTP only allows UNIQUE logical name under same level of hierarchy. As we see in the snapshot the two objects in Browser->Page node are “WebTable” and “testPath”, they cannot have the same logical name. But an object under some other node can have the same name. Now with the current repository that we have, we can only write operation on objects which are in the repository. Some of the example operations are given below

Browser("Browser").Page("Page").WebRadioGroup ("testPath").Select "2"
cellData = Browser("Browser").Page("Page").WebTable ("WebTable").GetCellData (1,1)
Browser("Example2").Page("Page").WebEdit("testPath").Set "Test text"

When and Why to use Descriptive programming?

Below are some of the situations when Descriptive Programming can be considered useful:

  1. 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 <>”.
  2. 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.
  3. 3. 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 repositoryScenario 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.

  4. Modification to a test case is needed but the Object repository for the same is Read only or in shared mode i.e. changes may affect other scripts as well.
  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.

How to use Descriptive programming?

There are two ways in which descriptive programming can be used

  1. By creating properties collection object for the description.
  2. By giving the description in form of the string arguments.

By creating properties collection object for the description.

To use this method you need first to create an empty description

Dim obj_Desc 'Not necessary to declare
Set obj_Desc = Description.Create

Now we have a blank description in “obj_Desc”. Each description has 3 properties “Name”, “Value” and “Regular Expression”.

obj_Desc("html tag").value= "INPUT"

When you use a property name for the first time the property is added to the collection and when you use it again the property is modified. By default each property that is defined is a regular expression. Suppose if we have the following description

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt.*"

This would mean an object with html tag as INPUT and name starting with txt. Now actually that “.*” was considered as regular expression. So, if you want the property “name” not to be recognized as a regular expression then you need to set the “regularexpression” property as FALSE

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt.*"
obj_Desc("name").regularexpression= "txt.*"

This is how of we create a description. Now below is the way we can use it

Browser("Browser").Page("Page").WebEdit(obj_Desc).set "Test"

When we say .WebEdit(obj_Desc) we define one more property for our description that was not earlier defined that is it’s a text box (because QTPs WebEdit boxes map to text boxes in a web page).

If we know that we have more than 1 element with same description on the page then we must define “index” property for the that description

Consider the HTML code given below

<input name="txt_Name" type="textbox" />
<input name="txt_Name" type="textbox" />

Now the html code has two objects with same description. So distinguish between these 2 objects we will use the “index” property. Here is the description for both the object

For 1st textbox:

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt_Name"
obj_Desc("index").value= "0"

For 2nd textbox:

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt_Name"
obj_Desc("index").value= "1"

Consider the HTML Code given below:

<input name="txt_Name" type="textbox" />
<input name="txt_Name" type="radio" />

We can use the same description for both the objects and still distinguish between both of them

obj_Desc("html tag").value= "INPUT"
obj_Desc("name").value= "txt_Name"

When I want to refer to the textbox then I will use the inside a WebEdit object and to refer to the radio button I will use the description object with the WebRadioGroup object.

Browser("Browser").Page("Page").WebEdit(obj_Desc).set "Test" 'Refers to the text box
Browser("Browser").Page("Page").WebRadioGroup(obj_Desc).set "Test" 'Refers to the radio button

But if we use WebElement object for the description then we must define the “index” property because for a webelement the current description would return two objects.

Hierarchy of test description

When using programmatic descriptions from a specific point within a test object hierarchy, you must continue to use programmatic descriptions
from that point onward within the same statement. If you specify a test object by its object repository name after other objects in the hierarchy have
been described using programmatic descriptions, QuickTest cannot identify the object.

For example, you can use Browser(Desc1).Page(Desc1).Link(desc3), since it uses programmatic descriptions throughout the entire test object hierarchy.
You can also use Browser(”Index”).Page(Desc1).Link(desc3), since it uses programmatic descriptions from a certain point in the description (starting
from the Page object description).

However, you cannot use Browser(Desc1).Page(Desc1).Link(”Example1″), since it uses programmatic descriptions for the Browser and Page objects but
then attempts to use an object repository name for the Link test object (QuickTest tries to locate the Link object based on its name, but cannot
locate it in the repository because the parent objects were specified using programmatic descriptions).

Getting Child Object

We can use description object to get all the objects on the page that matches that specific description. Suppose we have to check all the checkboxes present on a web page. So we will first create an object description for a checkboxe and then get all the checkboxes from the page

Dim obj_ChkDesc
 
Set obj_ChkDesc=Description.Create
obj_ChkDesc("html tag").value = "INPUT"
obj_ChkDesc("type").value = "checkbox"
 
Dim allCheckboxes, singleCheckBox
Set  allCheckboxes = Browse("Browser").Page("Page").ChildObjects(obj_ChkDesc)
 
dim i
For i = 0 to allCheckboxes.Count - 1
	singleCheckBox(i).Set "ON"
Next

The above code will check all the check boxes present on the page. To get all the child objects we need to specify an object description i.e. we can’t use the string arguments that will be discussed later in the 2nd way of using the programming description.

Possible Operation on Description Object

Consider the below code for all the solutions

Dim obj_ChkDesc
 
Set obj_ChkDesc=Description.Create
obj_ChkDesc("html tag").value = "INPUT"
obj_ChkDesc("type").value = "checkbox"

Q: How to get the no. of description defined in a collection

obj_ChkDesc.Count 'Will return 2 in our case

Q: How to remove a description from the collection

obj_ChkDesc.remove "html tag" 'would delete the html tag property from the collection

Q: How do I check if property exists or not in the collection?
A: The answer is that it’s not possible. Because whenever we try to access a property which is not defined its automatically added to the collection. The only way to determine is to check its value that is use a if statement “if obj_ChkDesc(”html tag”).value = empty then”.

Q: How to browse through all the properties of a properties collection?

For i=0 to obj_ChkDesc.count - 1
    Name= obj_ChkDesc(i).Name
    Value= obj_ChkDesc(i).Value
    RE = obj_ChkDesc(i).regularexpression
Next

By giving the description in form of the string arguments

You can describe an object directly in a statement by specifying property:=value pairs describing the object instead of specifying an object’s
name. The general syntax is:

TestObject("PropertyName1:=PropertyValue1", "..." , "PropertyNameX:=PropertyValueX")

TestObject-the test object class could be WebEdit, WebRadioGroup etc….

PropertyName:=PropertyValue-the test object property and its value. Each property:=value pair should be separated by commas and quotation
marks. Note that you can enter a variable name as the property value if you want to find an object based on property values you retrieve during a run session.

Consider the HTML Code given below:

<input name="txt_Name" type="textbox" />
<input name="txt_Name" type="radio" />

Now to refer to the textbox the statement would be as given below

Browser("Browser").Page("Page").WebEdit("Name:=txt_Name","html tag:=INPUT").set "Test"

And to refer to the radio button the statement would be as given below

Browser("Browser").Page("Page").WebRadioGroup("Name:=txt_Name","html tag:=INPUT").set "Test"

If we refer to them as a web element then we will have to distinguish between the 2 using the index property

'Refers to the textbox
Browser("Browser").Page("Page").WebElement("Name:=txt_Name","html tag:=INPUT","Index:=0").set "Test" 
 
'Refers to the radio button
Browser("Browser").Page("Page").WebElement("Name:=txt_Name","html tag:=INPUT","Index:=1").set "Test"
Rating: 6.0/10 (15 votes cast)
Sep
21
2008
0

Extending Dictionary Object

Dictionary object allows storing key value pairs. A dictionary object can be used for easy lookup of values. Dictionary is a not a QTP specific functionality and is available in normal VBScript as well.

Creating the Dictionary

A dictionary object can be created using CreateObject for COM class “Scripting.Dictionary”. The code below shows how to create the dictionary object in QTP

'Create the Dictionary Object
Set oDict = CreateObject("Scripting.Dictionary")

Methods

Below table shows list of methods that dictionary objects supports

Method

Description

Add (key, item)

Adds a key and item pair to a Dictionary object.

Exists(key)

Returns true if a specified key exists in the Dictionary object, false if it does not

Items()

Returns an array containing all the items in a Dictionary object

Keys()

Returns an array containing all existing keys in a Dictionary object.

Remove(key)

Removes a key, item pair from a Dictionary object

RemoveAll()

The RemoveAll method removes all key, item pairs from a Dictionary object.

Properties

Property

Description

Count Returns the number of items in a Dictionary object. Read-only.
Item Sets or returns an item for a specified key in a Dictionary object. Read/write
Key(Key) Sets a key in a Dictionary object

Adding Items to Dictionary

There are two ways to Add items to dictionary. One is to use the Add method and another is to use the Item property. Both the methods are shown in code below

'Method 1 for Adding items to dictionary
  'Add items to dictionary
  oDict.Add "CA", "California"
  oDict.Add "LA", "Los Angeles"
 
  'The below line will throw an error as LA key already exist
  oDict.Add "LA", "Los Angeles 2"
 
'Method 2 for adding items to dictionary
  oDict.Item("CA") = "California"
 
  'Item is the default property so ".Item" is not required
  oDict("LA") = "Los Angeles"
 
  'No Error this time as we are actually using the
  'Item property and not the Add method
  oDict("LA") = "Los Angeles 2"

Removing Items from Dictionary

Remove and RemoveAll methods allow to remove specified or all key(s) respectively. There usage is illustrated in the below code

'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
 
oDict("TX") = "Texas"
oDict("IND") = "India"
 
'Displays "Texas"
MsgBox oDict("TX")
 
oDict.Remove "TX"
 
'Displays "Empty". The keys has been deleted and
'does not exists and when we try to access a non
'existent key, a new Empty item is created
MsgBox oDict("TX")
 
'Displays "India"
MsgBox oDict("IND")
 
'Remove all the keys
oDict.RemoveAll
 
'Displays Empty
MsgBox oDict("IND")

Changing Keys

The key property can use to change key of any item

'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
 
oDict("IN") = "India"
 
'Change the IN key to IND
oDict.Key("IN") = "IND"
 
'Displays "India"
MsgBox oDict("IND")
 
'Displays "Empty"
MsgBox oDict("IN")
 
'Displays an error as the key IND is already
'associated with the value "India"
oDict.Key("IN") = "IND"

Checking Existence of an Item

We can check if an item exists or not using the exists methods as shown in code below

'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
 
oDict("IN") = "India"
 
'Change the IN key to IND
oDict.Key("IN") = "IND"
 
'Displays "India"
MsgBox oDict("IND")
 
'Displays "Empty"
MsgBox oDict("IN")
 
'Displays an error as the key IND is already
'associated with the value "India"
oDict.Key("IN") = "IND"

Enumerating contents of a Dictionary

Items and Keys method returns the array of Items and keys respectively. These methods cannot be directly used to access the values, there return array has to be first assigned to a variable and then accessed. The code below illustrates the enumerations

'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
 
oDict.Add "CA" , "California"
oDict.Add "LA" , "Los Angeles"
oDict.Add "TX" , "Texas"
 
aItems = oDict.Items
 
'Print all the items in the dictionary
For i = LBound(aItems) To UBound(aItems)
    Print aItems(i)
Next
 
'Print all keys in the dictionary
'We can use For each loop also to access the array
aKeys = oDict.Keys
For Each Key in aKeys
    Print "Key - " & Key
    Print "Value - " & oDict(Key)
Next

Compare Mode

CompareMode property of the dictionary can be used to set the text comparison mode for key. By default it is set to 0 (vbBinaryCompare) which means keys “TX” and “Tx” are different. Changing the value for CompareMode to 1 (vbTextCompare) will make “TX”, “tx”, “tX” and “Tx” to be treated as the same key. CompareMode can only be changed when there are no items in the dictionary

'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
 
oDict.Add "TX", "Texas"
 
'Will display Empty
MsgBox oDict("Tx")
 
'Remove all items
oDict.RemoveAll
 
'Changing the key comparison mode to text
oDict.CompareMode = vbTextCompare
 
oDict.Add "TX", "Texas"
 
'Displays Texas
MsgBox oDict("tx")
 
'The below line will throw an "Access is Denied" error
'As the property can only be changes when there are no
'items present in the dictionary
oDict.CompareMode = vbBinaryCompare

Using Dictionary to Hash Values

Dictionary objects support a HashVal method which can be used to get hashvalue for a text. This can be used when huge text arrays need to be compared. HashVal will always generate same values for same text.

'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
 
'Displays 0
MsgBox oDict.HashVal("")
 
'Displays 570
MsgBox oDict.HashVal("Tarun Lalwani")

Extending the Dictionary Functionality

Dictionary object does not allow saving and loading dictionary to and from files. We can extend the dictionary object by using VBScript classes. The extended will provide the following new functionalities

  • LoadFromFile to load the dictionary from a CSV file. This will remove all previous items
  • AddFromFile to add the item to current dictionary from a CSV file.
  • ExportToFile to export the dictionarty to a CSV file.
  • LoadFromDictionary to load the dictionary from a dictionary object. This will remove all previous items
  • AddFromDictionary to add items from another dictionary object
  • AccessUsingIndex property with True/False value to allow item access using index also. The actual dictionary object only allows to access items based on keys. But some times it is required to access items or keys based on index.

The code below shows the extended dictionary class

Class DictionaryEx
    'The actual dictionary that we will
    Private oDict
 
    'Private variable for storing value of AccessUsingIndex property
    Private mAccessUsingIndex
 
    'Now we need add all functions that the Dictionary already supports
    Public Property Get HashVal(Text)
        HashVal = oDict.HashVal(Text)
    End Property
 
    'Method to add a Key Value Pair
    Public Sub Add(ByVal Key, ByVal Item)
        oDict.Add Key, Item
    End Sub
 
    'Return the array of keys
    Public Function Keys()
        Keys = oDict.Keys
    End Function
 
    'Property to change key
    Public Property Let Key(oldKey, newKey)
        oDict.Key(oldKey) = newKey
    End Property
 
    'Returns array of items
    Public Function Items()
        Items = oDict.Items
    End Function
 
    'Check if certain key exists or not
    Public Function Exists(Key)
        Exists = oDict.Exists(Key)
    End Function
 
    'Remove All keys
    Public Sub RemoveAll()
        oDict.RemoveAll
    End Sub
 
    'Remove a specified key
    Public Sub Remove (Key)
        oDict.Remove GetKey(Key)
    End Sub
 
    'Get count of items in dictionary
    Public Property Get Count()
        Count = oDict.Count
    End Property
 
    'Get Property for CompareMode
    Public Property Get CompareMode()
        CompareMode = oDict.CompareMode
    End Property
 
    'Let Property for CompareMode
    Public Property Let CompareMode(newMode)
        oDict.CompareMode = newMode
    End Property
 
    'AccessUsingIndex is a flag which can be set to True/False
    'If Set to True then Numeric Keys will be translated to index
    'values and there corresponding keys will be used.
    'In case the numeric value is an existing key in the dictionary
    'then it would not be translated
    Public Property Get AccessUsingIndex()
        AccessUsingIndex = mAccessUsingIndex
    End Property
 
    'Let property for AccessUsingIndex
    Public Property Let AccessUsingIndex(newValue)
        If newValue = True Or newValue = False Then
            mAccessUsingIndex = newValue
        Else
            'If anything other then True/False raise an error
            Err.Raise vbObjectError + 1, "DictionaryEx", _
                "AccessUsingIndex can only be set true/false."
        End If
    End Property
 
    'Returns the actual dictionary object. This allows to do pass dictionary
    'to function which might support the actual dictionarty object
    Public Function Object()
        Set Object = oDict
    End Function
 
    'Function to translate keys from Index to actual key
    Private Function GetKey(Key)
        'Return actual key in case we are not
        'able to translate index to key
        GetKey = Key
 
        If Me.AccessUsingIndex Then
            'If the key already exist we do not want to change
            'anything even if it is a numeric value
            If Not oDict.Exists(Key) And IsNumeric(Key) Then
                keyIndex = CInt(Key)
                'Check if index is within range
                If keyIndex < Me.Count Then
                    Dim aKeys
 
                    aKeys = Me.Keys
 
                    'Translate from Index to Key
                    Key = aKeys(keyIndex)
                    Exit Function
                End If
            End If
        End If
    End Function
 
    'Item is the Default property for dictionary. So we
    'need to use default keyword with Property Get
    'Default keyword can be used with a only one Function
    'or Get Property
    Public Default Property Get Item(Key)
        'If a object is stored for the Key
        'then we need to use Set to return the object
        If IsObject(oDict.Item(GetKey(Key))) Then
            Set Item = oDict.Item(GetKey(Key))
        Else
            Item = oDict.Item(GetKey(Key))
        End If
    End Property
 
    'Let property Item
    Public Property Let Item(Key, Value)
        'Check of the value is an object
        If IsObject(Value) Then
            'The value is an object, use the Set method
            Set oDict(GetKey(Key)) = Value
        Else
            'The value is not an object assign it
            oDict(GetKey(Key)) = Value
        End If
    End Property
 
    'Property Set Item
    Public Property Set Item(Key, Value)
        Set oDict(GetKey(Key)) = Value
    End Property
 
    'AddFromDictionary takes an actual dictionary object and
    'add all keys from it
    Public Sub AddFromDictionary(oldDict)
        aKeys = oldDict.Keys
        Me.AccessUsingIndex = False
 
        For Each sKey In aKeys
            oDict(sKey) = oldDict(sKey)
        Next
    End Sub
 
    'LoadFromDictionary function removes all keys
    'and then add the keys from dictionary. It is
    'equivalent of creating a clone from a existing
    'dictionarty object
    Public Sub LoadFromDictionary(oldDict)
        oDict.RemoveAll
        Me.AddFromDictionary oldDict
    End Sub
 
    'Function to read dictionary key/value from file
    Public Sub AddFromFile(FileName, Delimiter)
        Set FSO = CreateObject("Scripting.FileSystemObject")
        Set oFile = Fso.OpenTextFile (FileName)
 
        'Read the file line by line
        While Not oFile.AtEndOfStream
            sLine = oFile.ReadLine
            KeyValue = Split(sLine, Delimiter)
            oDict(KeyValue(0)) = KeyValue(1)
        Wend
 
        Set oFile = Nothing
        Set FSO = Nothing
    End Sub
 
    'Function to remove all keys and then load it from
    'file
    Public Sub LoadFromFile(FileName, Delimiter)
        oDict.RemoveAll
        Me.AddFromFile FileName, Delimiter
    End Sub
 
    'Export the dictionarty to a file and use Delimiter
    'to seperate Key and Value pairs
    Public Sub ExportToFile(FileName, Delimeter)
        Set FSO = CreateObject("Scripting.FileSystemObject")
        Set oFile = FSO.CreateTextFile(FileName, True)
 
        Dim aKeys
        aKeys = oDict.Keys
 
        'Write the key value pairs line by line
        For Each sKey In aKeys
            oFile.WriteLine sKey & Delimeter & oDict(sKey)
        Next
 
        'Close the file
        oFile.Close
 
        Set oFile = Nothing
        Set FSO = Nothing
    End Sub
 
    'Intialize event gets executed whenever a object is created
    Sub Class_Initialize()
        Set oDict = CreateObject("Scripting.Dictionary")
        Me.AccessUsingIndex = False
    End Sub
 
    'Executed when the object is destroyed
    Sub Class_Terminate()
        'Remove all the keys
        oDict.RemoveAll
 
        'Destroy the dictionary
        Set oDict = Nothing
    End Sub
End Class

Below code illustrates the usage of the extended dictionary.

Set xDict1 = New DictionaryEx
Set xDict2 = New DictionaryEx
xDict1("CA") = "California"
xDict1("IND") = "India"
xDict1("FL") = "Florida"
 
'Export the dictionary
xDict1.ExportToFile "C:\Dict.txt", "###"
 
'Load dictionarty from file
xDict2.LoadFromFile "C:\Dict.txt", "###"
 
'Displays India
MsgBox xDict2("IND")
 
Set oDict = xDict2.Object
 
'Display Florida
MsgBox oDict("FL")
 
xDict2.AccessUsingIndex = True
 
'Displays "California"
MsgBox xDict2(0)
 
'Displays "India"
MsgBox xDict2("IND")
 
'Displays "India"
MsgBox xDict2(1)

In case you add the DictionaryEx class to a VBS file and associate it to the Test; Trying to create a object of DictionaryEx class will cause an error. This happens because global libraries in QTP are loaded outside the action scope and the classes are not visible to the action scope. The workaround is to create a function in the VBS that creates the object and returns it reference

Public Function NewDictionaryEx()
    Set NewDictionaryEx = New DictionaryEx
End Function

Dictionaries as Reserved Object in QTP

QTP allows adding any COM object as reserved object by adding its information to the Registry. To add Dictionary as one of the objects, follow the below mentioned steps

  • Open Regedit.exe through windows run window
  • Browse to HKEY_CURRENT_USER\Software\Mercury Interactive\QuickTest Professional\MicTest\ReservedObjects
  • Create a new key under this key with Name as “Dictionary” and as String value “ProgID” with data as “Scripting.Dictionary” as shown in below screenshot

    Registry Editor

    Registry Editor

  • Start QTP, type “Dictionary.” and we will not get the intellisense for the same as shown in the image below

    Dictionary as Reserved object

    Dictionary as Reserved object

Summary

In this article we learned

  • How to use dictionary objects
  • Extending the dictionary objects
  • Using dictionary object as Reserved QTP objects
Rating: 10.0/10 (3 votes cast)
Sep
21
2008
0

QTP FAQ, Tips & Tricks

The article provides answers to most frequently asked question on Quick test pro 8.2. It also provides some tips and tricks. A must read for people working on QTP.

Data Table

Two Types of data tables

  • Global data sheet: Accessible to all the actions
  • Local data sheet: Accessible to the associated action only

Usage:

DataTable("Column Name",dtGlobalSheet) for Global data sheet
 
DataTable("Column Name",dtLocalSheet) for Local data sheet

If we change any thing in the Data Table at Run-Time the data is changed only in the run-time data table. The run-time data table is accessible only through then test result. The run-time data table can also be exported using DataTable.Export or DataTable.ExportSheet

How can i save the changes to my DataTable in the test itself?

Well QTP does not allow anything for saving the run time changes to the actual data sheet. The work around is to share the spreadsheet and then access it using the Excel COM Api’s.

How can I check if a parameter exists in DataTable or not?

The best way would be to use the below code:

On Error Resume Next
Val = DataTable("ParamName", dtGlobalSheet)
If Err.Number<> 0 Then
    'Parameter does not exist
Else
    'Parameter exists
End If

How can i make some rows colored in the data table?

Well you can’t do it normally but you can use Excel COM API’s do the same. Below code will explain some expects of Excel COM APIs

rowsCount = xlWorkSheet.Evaluate("COUNTA(A:A)")
 
'Will count the # of non blank columns in 1st row
colsCount = xlWorkSheet.Evaluate("COUNTA(1:1)")
 
xlWorkbook.SaveAs "C:\Test.xls"
xlWorkBook.Close
Set xlWorkSheet = Nothing
Set xlWorkBook = Nothing
Set xlApp = Nothing

SMART Identification

Smart Identification is nothing but an algorithm used by QTP when it is not able to recognize one of the object. A very generic example as per the QTP manual would be, A photograph of a 8 year old girl and boy and QTP records identification properties of that girl when she was 8, now when both are 10 years old then QTP would not be able to recognize the girl. But there is something that is still the same, that is there is only one girl in the photograph. So it kind of PI (Programmed intelligence) not AI.

When should i use SMART Identification?

Something that people don’t think about too much. But the thing is that you should disable SI while creating your test cases. So that you are able to recognize the objects that are dynamic or inconsistent in their properties. When the script has been created, the SI should be enabled, so that the script does not fail in case of small changes. But the developer of the script should always check for the test results to verify if the SI feature was used to identify a object or not. Sometimes SI needs to be disabled for particular objects in the OR, this is advisable when you use SetTOProperty to change any of the TO properties of an object and especially ordinal identifiers like index, location and creationtime.

Descriptive Programming

Descriptive programming is nothing but a technique using which operations can be performed on the AUT object which are not present in the OR. For more details refer Descriptive Programming in QTP

Recovery Scenarios

What is a Recovery Scenario?

Recovery scenario gives you an option to take some action for recovering from a fatal error in the test. The error could range in from occasional to typical errors. Occasional error would be like “Out of paper” popup error while printing something and typical errors would be like “object is disabled” or “object not found”. A test case have more then one scenario associated with it and also have the priority or order in which it should be checked.

What does a Recovery Scenario consists of?

  • Trigger: Trigger is nothing but the cause for initiating the recovery scenario. It could be any popup window, any test error, particular state of an object or any application error.
  • Action: Action defines what needs to be done if scenario has been triggered. It can consist of a mouse/keyboard event, close application, call a recovery function defined in library file or restart windows. You can have a series of all the specified actions.
  • Post-recovery operation: Basically defined what need to be done after the recovery action has been taken. It could be to repeat the step, move to next step etc….

When to use a Recovery Scenario and when to us on error resume next?

Recovery scenarios are used when you cannot predict at what step the error can occur or when you know that error won’t occur in your QTP script but could occur in the world outside QTP, again the example would be “out of paper”, as this error is caused by printer device driver. “On error resume next” should be used when you know if an error is expected and dont want to raise it, you may want to have different actions depending upon the error that occurred. Use err.number & err.description to get more details about the error.

Library Files or VBScript Files

How do we associate a library file with a test ?

Library files are files containing normal VBScript code. The file can contain function, sub procedure, classes etc…. You can also use executefile function to include a file at run-time also. To associate a library file with your script go to Test->Settings… and add your library file to resources tab.

When to associate a library file with a test and when to use execute file?

When we associate a library file with the test, then all the functions within that library are available to all the actions present in the test. But when we use Executefile function to load a library file, then the function are available in the action that called executefile. By associated a library to a test we share variables across action (global variables basically), using association also makes it possible to execute code as soon as the script runs because while loading the script on startup QTP executes all the code on the global scope. We can use executefile in a library file associated with the test to load dynamic files and they will be available to all the actions in the test.

Test and Run-time Object

What is the difference between Test Objects and Run Time Objects ?

Test objects are basic and generic objects that QTP recognize. Run time object means the actual object to which a test object maps.

Can i change properties of a test object?

Yes. You can use SetTOProperty to change the test object properties. It is recommended that you switch off the Smart Identification for the object on which you use SetTOProperty function.

Can i change properties of a run time object?

No (but Yes also). You can use GetROProperty(”outerText”) to get the outerText of a object but there is no function like SetROProperty to change this property. But you can use WebElement().object.outerText=”Something” to change the property.

Action & Functions

What is the difference between an Action and a function?

Action is a thing specific to QTP while functions are a generic thing which is a feature of VB Scripting. Action can have a object repository associated with it while a function can’t. A function is just lines of code with some/none parameters and a single return value while an action can have more than one output parameters.

Where to use function or action?

Well answer depends on the scenario. If you want to use the OR feature then you have to go for Action only. If the functionality is not about any automation script i.e. a function like getting a string between to specific characters, now this is something not specific to QTP and can be done on pure VB Script, so this should be done in a function and not an action. Code specific to QTP can also be put into an function using DP. Decision of using function/action depends on what any one would be comfortable using in a given situation.

Checkpoint & Output value

What is checkpoint?

Checkpoint is basically a point in the test which validates for truthfulness of a specific things in the AUT. There are different types of checkpoints depending on the type of data that needs to be tested in the AUT. It can be text, image/bitmap, attributes, XML etc….

What’s the difference between a checkpoint and output value?

Checkpoint only checks for the specific attribute of an object in AUT while Output value can output those attributes value to a column in data table.

How can i check if a checkpoint passes or not?

chk_PassFail = Browser(...).Page(...).WebEdit(...).Check (Checkpoint("Check1"))
If chk_PassFail Then
    MsgBox "Check Point passed"
Else
    MsgBox "Check Point failed"
End If

My test fails due to checkpoint failing, Can i validate a checkpoint without my test failing due to checpoint failure?

'Disables all the reporting stuff
Reporter.Filter = rfDisableAll
 
chk_PassFail = Browser(...).Page(...).WebEdit(...).Check (Checkpoint("Check1"))
 
'Enable all the reporting stuff
Reporter.Filter = rfEnableAll
 
If chk_PassFail Then
    MsgBox "Check Point passed"
Else
    MsgBox "Check Point failed"
End If

Environment

How can i import environment from a file on disk

Environment.LoadFromFile "C:\Env.xml"

How can I check if an environment variable exists or not?

When we use Environment(”Param1″).value then QTP expects the environment variable to be already defined. But when we use Environment.value(”Param1″) then QTP will create a new internal environment variable if it does not exists already. So to be sure that variable exist in the environment try using Environment(”Param1″).value.

How to connect to a database in QTP?

Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adUseClient = 3
 
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")
 
objConnection.Open "DRIVER={Microsoft ODBC for Oracle};UID=;PWD=
"
 
objRecordset.CursorLocation = adUseClient
objRecordset.CursorType = adopenstatic
objRecordset.LockType = adlockoptimistic
 
ObjRecordset.Source = "select field1,field2 from testTable"
ObjRecordset.ActiveConnection = ObjConnection
ObjRecordset.Open 'This will execute your Query
 
If ObjRecordset.recordcount>0 Then
    Field1 = ObjRecordset("Field1").Value
    Field2 = ObjRecordset("Field2").Value
End If