May 30 2008

Add New Methods to Objects

This short article complements a previous one I have published on how to Override the Object Exist Property. As previously indicated, 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. In this brief article we will see that it is also technically possible to add object methods, thus expanding the ways by which objects can be handled. For example, one might wish to get the background color of a row in a WebTable or ListView, or to check that if specific values are displayed, the font color and style are as expected. This is obviously very useful, since again we can gain from registering such generic functions and reusing them afterwards across tests, applications and projects.

The method for implementing such an extensibility follows the same lines outlined in Yaron Assa’s “A Fresh Look on RegisterUserFunc” (2008) and my own previous article in which I explained the motivation to override the objects’ Exist property.

The implementation steps are:

  1. Analyze the requirement (to which object classes it’s relevant, etc.);
  2. Design the solution;
  3. Code the function (keep in mind that any function to be registered to an object class must get a ByRef obj argument as in the example below);
  4. Test the function;
  5. Register the function to the required object classes;
  6. Test that it is added to the object class or classes using the QTP editor’s intellisense or by inserting a step (pressing F7 in QTP GUI during design time). Test that using the function this way works properly.

The example below shows a NotExists function that complements the Exist property overriding mentioned in my previous article. Addressing the Analyze phase suggested above, it might be questioned why one needs a separate registered function to check for object inexistence instead of using the aforementioned Exists function with a Negation (Not) command. The need is fundamental, as when one wishes to check for a Window or Browser having closed properly. Well, again the motivation stems from QTP’s weird and unreliable behavior with respect to this basic object detection functionality. I tried to use it this way (i.e., by putting a Not obj.Exists(0) statement) and actually QTP got stuck in too many cases. My conclusion so far is that since using the Exist functionality is basically for the purpose of detecting the existence of an object (i.e., that it is indeed loaded to memory), then to check for object inexistence one needs a similar mechanism to the proposed Exists, but with a reversed logic.

So, the following function emerged:

Public Function NotExists(ByRef obj, ByVal intTimeoutMSec)
'Function : NotExists
'Waits until an object is unloaded or the specified timeout expires.
'Comment : It's possible to register this function to any object class using:
' RegisterUserFunc <Class>, "NotExists", "NotExists"
'Arguments : ByRef obj - Any Object
' ByVal intTimeoutMSec
'Returns : True - if object unloaded 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

    'Ensure the Timeout argument is an integer (Environment vars are parsed as strings)
    intTimeoutMSec = CInt(intTimeoutMSec)

    Set objTimer = MercuryTimers.Timer("ObjectExistTimer")

        NotExists = Not obj.Exist(0)
        If NotExists Then
            Exit Do
        End If
        Wait Environment("DEFAULT_SAMPLING_INTERVAL_SEC"), _
    Loop Until objTimer.ElapsedTime > intTimeoutMSec
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” (Bar-Tal, 2008b). As far as observed, this function works reliably and QTP does not get stuck when using the function.

As pointed out in the articles mentioned above, one great benefit of method registration is the ability to maintain code very efficiently. So, to be able to continue to use this function across tests, applications and projects  without changing a single line of code, all we need to do is, taking the Browser class for example:

RegisterUserFunc "Browser", "NotExists", "NotExists"

Of course, this must be done for each object class as required.

To summarize, QTP’s RegisterUserFunc method enables also to add object methods. The case of adding an overridden version of checking for unloaded objects with the unreliable Exist property was briefly introduced and a way of implementing and registering such a method was exemplified.

About Meir Bar-Tal

Meir Bar-Tal is an Automation Architect with extensive technical, educational and leadership experience in Software Design, Development and Testing. For many years Meir has helped companies establish solid foundations for their testing activities with a wide variety of software applications and systems and across different technologies and platforms. Meir is a well-known expert in Data-Driven, Keyword Driven and Hybrid methodologies and has published a number of influential articles on the applications of Design Patterns to Test Automation. For the last five years, he has been pushing forward an ambitious program towards the development of an Object Oriented automation framework named Sunscrit, a huge project which is still underway. Meir is the owner of www.AdvancedQTP.com of which he was a co-founder in 2007 and served as its Editor in Chief, Author and Forums Administrator ever since. Meir lives in Israel and cooperates closely with HP R&D and other colleagues to improve the user experience and productivity with HP Software tools.