One of the most powerful features QuickTest Professional (QTP) provides is the ability to override methods of object classes with custom functions tailored to serve specific purposes. For example, the WebEdit.Set method might be expanded to first check if a popup message is open before or after (or both) the set operation took place. This can be helpful to avoid the use of a recovery scenario which brings its performance costs with unreliable results.
This topic has already been addressed by Yaron Assa in "A Fresh Look on RegisterUserFunc" (2008). In this brief article we will see that it is also technically possible to override object properties. True, QTP provides only two properties for the GUI object classes: Exist and Object. So, it might be asked why has one to bother with a technicality that has such a limited potential use. However, the motivation to override the Exist property stems from the complex and unreliable fashion in which QTP behaves when asked about an object’s existence. For example, sometimes it seems that QTP treats the timeout as a mere recommendation, going on and on checking if the object exists, to the point that it simply gets stuck. So, after conducting some experiments the following function evolved:
'*******************************************************************************
Public Function Exists(ByRef obj, ByVal intTimeoutMSec)
'*******************************************************************************
'Function: Exists
' Waits until an object is loaded or the specified timeout expires.
'
'Comment:
' It’s possible to register this function to any object class using:
' RegisterUserFunc <Class>, "Exist", "Exists"
'
'Arguments:
' ByRef obj - Any Object
' ByVal intTimeoutMSec
'
'Returns:
' True - if object is loaded within the specified timeout.
' False - if the timeout expired.
'
'Developed By:
' Meir Bar-Tal
'
'Date:
' 14-May-2008
'
'****************************************************************************** *
Dim objTimer
If Not IsNumeric(intTimeoutMSec) Then
intTimeoutMSec = Environment("DEFAULT_TIMEOUT_MSEC")
End If
Set objTimer = MercuryTimers.Timer("ObjectExist")
objTimer.Start
Do
Exists = obj.Exist(0)
If Exists Then
objTimer.Stop
Exit Do
End If
Wait Environment("DEFAULT_SAMPLING_INTERVAL_SEC"), _
Environment ("DEFAULT_SAMPLING_INTERVAL_MSEC")
Loop Until objTimer.ElapsedTime > intTimeoutMSec
objTimer.Stop
'*******************************************************************************
End Function
'*******************************************************************************
Actually here the Exist property is used in a special way: an immediate response is requested every time, and the sampling interval (i.e., the delay between each time QTP checks for object existence) is controlled using Environment variables. This function is the last version of my experiments, and as far as observed it works reliably. QTP does not get stuck when using the function.
As Yaron pointed out in the article mentioned above, one great benefit of method overriding is the ability to maintain code very efficiently. So, to be able to continue to use obj.Exist in the scripts without changing a single line of code, all we need to do is, taking the Browser class for example:
RegisterUserFunc "Browser", "Exist", "Exists"
Of course, this must be done for each object class.
To summarize, QTP’s RegisterUserFunc method enables also to override object properties. The case of the unreliable Exist property was briefly introduced and a way of implementing such property overriding was exemplified.
Posted in Meir Bar-Tal's Blog, QTP Hacks


Meir Bar-Tal




May 19th, 2008 at 5:27 pm
This is good. I had never tried this before because I didn’t understand how it would work.
If obj is a Browser object, and browser.exist is registered to exists, I thought the line “Exists = obj.Exist(0)” would just call itself and create an infinite loop. Now that I have tried it, I see that it is actually calling the original exist function.
May 26th, 2008 at 6:42 am
This was very useful and good.
May 29th, 2008 at 1:06 am
Very useful, Thanks guys.
I found that the “unreliability” of the exists method seems to occur alot more when you embed actions within your QTP Tests. i.e. Using a “RunAction” to call another QTP test (usually a component).
I contacted HP (or then Mercury) and they have more of less said it may be a bug.
July 21st, 2008 at 3:59 pm
why can’t we use if else along with exist statement.
My opinion is
if object hierarchy.exist then
‘do the following
….
….
….
else
‘do the following
….
….
….
end if
July 23rd, 2008 at 8:40 pm
I’d like to know what sampling values are suggested for this function. Is there any consequence for letting the function run at top speed?
July 23rd, 2008 at 11:10 pm
I’m using 0 seconds, 250 milliseconds. Too fast is dangerous because QTP needs time to get a response from the OS.