Login   /   Register

A Fresh Look on RegisterUserFunc

Rate this article
     2 votes, average: 4.5 out of 52 votes, average: 4.5 out of 52 votes, average: 4.5 out of 52 votes, average: 4.5 out of 52 votes, average: 4.5 out of 5
Loading ... Loading ...
March 30th, 2008 by Yaron Assa

Background

Today we’re going to deal with an often overlooked feature of QTP – RegisterUserFunc. Though RegisterUserFunc can offer some real-world benefits, newcomers to the QTP world are unfamiliar with it, and QTP experts look down on it (when comparing it to their custom frameworks). I intend to shed some new light on this feature and its inherent possibilities, and make it more accessible to and appealing to newcomers and experts alike.

RegisterUserFunc allows you to add a new method or override an existing method for a certain QTP class. For example, you can add a new method called "Move20″ to all VBWindows in your scripts, which will move them 20 pixels to the right; or override the VBWindow "Close" method by adding your own code for dealing with "save changes" pop-ups that may appear when you try to close them.

Either way, RegisterUserFunc shifts the way of extending your scripts power and functionality from writing functions which receive objects and operate on them, to adding methods to the relevant objects themselves.


Syntax

Using RegisterUserFunc is rather simple, and is comprised to two phases.

First, we write the code for the new method as a function, which receives at least one parameter. We can functions methods that receive more than one parameter, thus making it possible to override methods such as Set or Select (which require sending the desired new value as a parameter by itself). The first parameter the function receives is always the object that initiated the method. So if we take the previous example, our function will look like this:

Function MyClose(oWindow)
    Dim iTimer 'Will help us count time
 
    iTimer = Timer
    oWindow.Close 'Initiate the VBWindow original close command 
    
    Do
        If Dialog("micclass:=Dialog").Exist(0) Then _
             Dialog("micclass:=Dialog").Type MicEsc 
            'Deal with any pop-ups
    Loop Until (Not oWindow.Exist) Or (Timer-iTimer>15)
 
    'Wait for the window to close or the command to time out
    If oWindow.Exist Then
      MyClose = False
    Else
      MyClose = True
    End If
End Function

After that, we need to actually register our new method to the VBWindow QTP class. This is done with the RegisterUserFunc command (for the complete command syntax, see QTP help):

RegisterUserFunc "VBWindow", "Close", "MyClose"

This will register the function MyClose, as a VBWindow’s class method named "Closed". Since this QTP class already has a method called Closed, our new method will override it for this run-session.

Scope and deregistration

It’s important to note that the scope of RegisterUserFunc is determined by the scope of the code it was called from. So for example, if we call RegisterUserFunc from within an action, it will not affect the objects in other actions (though they may be used in the same run-session). To achieve a more global effect, you should place both the function code and the RegisterUserFunc command in an external vbs, and link it to your tests.

Moreover, if at some point DURING the run-session you’d like to remove your method from the QTPClass, you can use UnRegisterUserFunc to do so. QTP help advises you to UnRegisterUserFunc any method that was registered within the scope of the current action, though I don’t really understand why.

Maintenance and RegisterUserFunc

While the common opinion among QTP experts is that RegisterUserFunc is no match for a well-built custom framework, it still has its benefits and merits - The central one being the ability to apply script-wide code-fixes without changing a single line of existing code.

Imaging the following situation – you have a wide system of scripts automating an AUT which contains comboboxes. After a while, the client comes with a new requirement - select an unknown random value in the comboboxes.

Now, in the preferable situation, you have a custom framework wrapping the input command for the AUT’s controls, and you can easily introduce the needed code in one central place, and get done with it (for example, this is the case with FrameworkManager).  However, if you don’t have such a framework, adding the new code becomes a hellish run of all the tests and scripts, fixing every code-line that deals with inputting comboboxes.

RegisterUserFunc can save you all those nitpicking micro code-fixes. You can write an extended function that will manage the random value selection, and override the combobox default .Select method with it. This way, you can implement the new behavior throughout all your tests and scripting with a single command. Here’s a possible implementation for the function:

Function ComboSelectWithRandom(oCombo, sNewValue)
    Dim iRndValue
    Dim arrAllValues
 
    If uCase(sNewValue) = "RANDOM" Then
        'Transform the comboboxes "all values" property into an array
        arrAllValues = Split(oCombo.GetROProperty("all items"), chr(10))
        'Randomly select a new value
        iRndValue=RandomNumber.Value(0, uBound(arrAllValues))
        sNewValue = arrAllValues(iRndValue)
    End If
    
    'Try actual value selection
    On Error Resume Next
        oCombo.Select sNewValue
        If Err.Number <> 0 Then
            ComboSelectWithRandom = False
        Else
            ComboSelectWithRandom = True
        End If
    On Error Goto 0
End Function

And now we only need to override the default .Select command:

RegisterUserFunc "VbComboBox", "Select", " ComboSelectWithRandom"

And we can immediately start selecting "Random" in all our scripts and tests. So while it’s better to have a robust framework that will save you these emergencies, if you’re already knee-deep in a crises, RegisterUserFunc can help you get out of it in a fast and easy manner.

Posted in QTP Techniques

6 Responses to “A Fresh Look on RegisterUserFunc”

  1. Override the Object Exist Property with RegisterUserFunc | AdvancedQTP Says:

    [+]

    [...] topic has already been addressed by Yaron Assa in "A Fresh Look on RegisterUserFunc" (2008). In this brief article we will s... ...

  2. heqingbluesky Says:

    [-]

    Pretty useful for override existing user-defined or system-defined function without affecting the original framework or function.

  3. Add New Methods to Objects | AdvancedQTP Says:

    [+]

    [...] method for implementing such an extensibility follows the same lines outlined in Yaron Assa’s "A Fresh Look on Registe... ...

  4. lbx111111 Says:

    [-]

    very good

  5. qakapil Says:

    [+]

    Nice article. I would be inerested to know that how we can use the above method instead of Recovery Scenario in QTP. Agreed that t... ...

  6. mohantyajaya Says:

    [-]

    This seems pretty good, but have you ever used it? Like I want to know some situation where this will be useful.

Leave a Reply

You must be logged in to post a comment.

This article was viewed 1707 times