Understanding the Web Test Object Model in HP Unified Functional Testing (UFT)

7 10 2018

In 2013 I wrote a technical blog post for work. Since then the company was purchased by Micro Focus and the post has disappeared (probably due to branding issues). I’m re-posting it here (with minor changes) for future reference. Opinions expressed here are my own and do not represent those of Micro Focus or its entities.

The terms QTP (QuickTest Professional) and UFT are used interchangeably.

The meaning of the following script line should be obvious to anyone using UFT:

                Browser("B").Page("P").Link("L").Click

It says “Click link ‘L’ on page ‘P’ of the browser ‘B’.  But are things really that simple? Let’s drill down into each part of this step in order to understand why UFT’s designers chose to represent objects in this specific way.

Objectives of the Object Model

When deciding how to represent an object in an Application Under Test (AUT) several considerations are taken into account:

  • Robustness – A test should fail only if there is something wrong with the functionality of the AUT. Changes with no functional effects (e.g. font change) should not affect the test outcome.
  • Maintainability – If the AUT changes in a way that affects the test it should be easy to update the test in order to accommodate the changes in the AUT. This consideration gives rise to sub-considerations:
    • Readability -It should be obvious what a test does by reading it
    • Organization – Objects in the object repository should be organized in a logical manner so that it will be easy to find an object when looking for it.

Browser

What is a Browser?

Today, a Browser is a tab. But before tabs were introduced, a browser was a software application used to access the World Wide Web.  The object hierarchy was very simple:

Browser("B").Page("P")

With the advent of tabbed browsers, we had to decide how QTP should represent a tab. The naïve answer would be to just add another level to the object hierarchy:

Browser("B").Tab("T").Page("P")

But this has the following drawbacks:

  • Tests created on a tabbed browser will not work with a non-tabbed browser (even if only one tab is ever used)
  • Placing the tab under a specific browser is rarely a functional issue, as it breaks the robustness objective we discussed at the beginning of this article. A web page should be rendered identically whether it is created in a separate top-level window or as another tab

The drawbacks to having the Browser object represent a specific tab were mostly esthetic, but it was still the best option.

Because there may be some functional significance to having separate tabs in the same browser, we added the OpenNewTab, IsSiblingTab and CloseAllTab methods to the Browser test object. I’d like to know if anyone actually uses them… please leave me  a comment below to let us know if you do.

Nowadays, tabs can be ‘torn off’ from one browser instance and onto another.  So it seems clear that we made the correct decision.

Note: A minor compatibility issue that arose from this was that the window handle (HWND) for the Browser no longer refers to the top-level window.  Creating a regular Window test object with this HWND won’t allow you to call the Minimize or Move methods, or indeed call any other method which is available in Window but not in Browser.

A Browser’s ‘Description’

The object identification dialog doesn’t list properties for a browser’s description. This means that if more than one browser is open, the description will use an ordinal identifier, by default, creation time:

browser-desc

There isn’t actually a generic way to distinguish between browsers. Let’s say you open a browser on your homepage, navigate to your mail account to see what’s new, hang out in Facebook, and then navigate to your business application and start running tests.   If UFT used title as a default description property, the object repository would have many browser test objects – one for the homepage, one for mail, one for Facebook, etc. – and it would be very hard to find the correct browser.  This breaks the organization principle discussed earlier.

But if there is a consistent pattern to how you use your browsers, you can create a more robust description by using the opentitle, openurl or openedbytestingtool properties. For example, this screenshot shows how to use opentitle for all new browser objects, in the Object Identification dialog:

opentitle

This screenshot shows how to use openurl for a specific browser:

openurl

And the following line of script shows how you can use descriptive programming to refresh a browser by its openurl property:

Browser("openurl:=http://www.hp.com").Refresh

Page

The Page object represents the top-level HTML document displayed in the current Browser. Since there can be only one top-level HTML document each Browser will have only one page. So why do we need another layer in the hierarchy? Why not just make the Browser object represent the top-level HTML document as well as the tab window?

The answer is to preserve the test maintainability objective we described earlier.  We determined that we don’t want to create a new Browser test object whenever the HTML being displayed changes, but this may lead to having tests with many dozens (hundreds?) of test objects under the Browser. In order to prevent this, we create an artificial split so that the controls that appear under the same Page test object logically belong together.

Thus if you have a login page and an accounts page you can find the username edit field without sifting through all the test objects that appear in the accounts page, because the appropriate controls are grouped logically.

Tip: You can modify the amount of page test objects created in UFT in Options > Web > Page/Frame Options

Frame

A Frame object represents an HTML document under the main object (inside a FRAMESET or IFRAME).  There’s nothing particularly interesting about this, so let’s move on…

WebElement(s)

Under the Frame (or Page) object, all the web test objects (Link, WebButton etc.) are siblings.  But this isn’t how they appear in the actual HTML – the actual elements in an HTML document are typically nested in a deep hierarchy:

elem-dom

A typical web hierarchy as viewed with IE’s developer tools

Not only would adding all parent elements to the test make the test unreadable, it would also mean that the test will fail for every minor change in the HTML, and break our readability and robustness objectives respectively.

Although UFT flattens out the hierarchy when recording or learning an object, you can still create a hierarchy by yourself. If you drag a WebCheckBox (or any other object) under a WebElement in the Object Repository (or just nest them using descriptive programming) UFT will only look for the checkbox under its parent test object. This means that the description you give for the WebCheckBox only has to achieve uniqueness relative to its container, which can simplify things immensely for applications that contain many similar elements (such as the Add to cart link on an online store).  For example, the following screenshot shows how the HP Slate 7’s ‘Add to cart’ link on HP’s online store appears in the Object Repository Manager.  It is directly underneath the ‘Slate | HP Official Store’ page (other test objects were removed for clarity in the screenshot):

under-page

The ‘Add to cart’ link appears many times on the page, since there are many items which can be purchased.  This specific one is the third one (ie. having an index of 2) on the page.  UFT will have to find the first two links until it can locate the third one

We can simplify it by adding the context element of HP Slate 7 to the hierarchy.  In this way, UFT only needs to locate the HP Slate 7, and then find the only ‘Add to cart’ link in the context of the HP Slate 7.  Since there’s only one link, we don’t even need the ordinal identifier:

under-item

HTML Tag

By default, UFT uses the html tag property as part of the description of all web test objects, even those for which it’s pretty obvious what the tag name will be.

tagName

The reason for this is that in order to identify a test object UFT must check all the elements on the page to see whether they fit the description, and this can be slow for big pages with thousands of element.  But browsers support getting the elements of a specific tag, and if UFT can use this function it can perform the search on far fewer elements. Because the html tag is part of the description by default you don’t usually have to think about it.  But if you change an object’s description (in the object repository or in the object identification dialog) you should keep this in mind.  If you use descriptive programming and you’re seeing that performance is a bit slow, consider adding the html tag to the description.

Note to WebExtensibility authors:  Consider adding the html tag property to the description of new types.

In Conclusion

I hope that after reading this post you have a better understanding of why UFT represents controls the way it does (at least in the Web addin). Some things that might have seemed arbitrary should now make some sense. You may have even picked up a tip or two that will help you improve your web tests!

Advertisements




How UFT Identifies Objects

20 09 2018

In 2010 I wrote a technical blog post for work. Since then the company was purchased by Micro Focus and the post has disappeared (probably due to branding issues). I’m re-posting it here (with minor changes) for future reference. Opinions expressed here are my own and do not represent those of Micro Focus or its entities.

The terms QTP (QuickTest Professional) and UFT are used interchangeably.

 

Note: The following describes the inner workings of QuickTest, it is intended to help people understand how things work but may change in future versions and shouldn’t be depended on.

QuickTest Professional’s bread and butter is identifying controls in the application being tested and it faces a tough decision since there are two directions in which one can optimize.

  • Optimize for speed
  • Optimize for robustness

Unfortunately one usually comes at the price of the other.

In order to alleviate this problem QuickTest has two concepts called description and runtime ID which are used together in order to achieve the best of both worlds.

Description

You should be familiar with the method QuickTest uses to identify Test Objects, this is a set of property/value pairs which (given the Test Object’s parent) describe an object uniquely.

object identification dialog

This description can be used to describe a control robustly so that it will still match the correct control even when run in a different environment and in different builds of the application. However finding the object that matches this description may be slow.

Runtime ID

A runtime ID is a way to quickly identify a control in the application being tested, the actual implementation changes according to the technology in question but first a bit of background.

In Microsoft Windows each control has a Window which is identified by a handle (known as HWND for “Handle to WiNDow”). All the Windows APIs use HWNDs to access controls and this method is very fast. However the HWND must be considered a “black box” you can’t assume anything about its value since Windows assigns each control an HWND from an internal pool and the value will change every time the application is run. This makes an HWND the perfect match to be the runtime ID of Win32 controls, for example a WinButton Test Object’s runtime ID may be its HWND.

Combining the Two

The characteristics of runtime IDs and descriptions are summarized in the following table:

  Runtime ID Description
Fast Yes No
Persistent No Yes
Unique Globally Under container

Every Test Object may contain a runtime ID and/or a description, if both are missing there is no way to identify the control in the application being tested and the Test Object is useless (with a few exceptions).

When a Test Object is created from the application being tested it contains a runtime ID and if the Test Object is to be stored in the Object Repository (during learn or record) a description is created for this Test Object.

When running a test the Test Object has its description filled in (either from the Object Repository or from Programmatic Description) and then its runtime ID is found. Since finding the runtime ID is potentially an expensive operation the value of the runtime ID is cached so as not fetch it multiple times. However since the runtime ID may change during the test run QuickTest is careful to clear the stored value whenever a new step is run. This means that if you store the Test Object in a variable or use With the aforementioned runtime ID clearing will not take place and the runtime ID may be invalidated. If this happens you can call the RefreshObject method available since QuickTest 10 which manually clears the runtime ID.

invalidating a runtime ID

An unexpected pitfall came as a support call when a customer tried to call Exist on a Test Object returned from ChildObjects, let’s follow the chain of events with our new found knowledge of the inner workings of QuickTest.

  1. ChildObjects creates Test Objects with their runtime IDs set (the Test Objects are to be used immediately so there no point in creating their descriptions)
  2. Exist wants to check if the object still corresponds to a control in the application being tested, to do this it clears the runtime ID and tries to re-create it
    1. The description is empty so Exist fails
  3. Further down the line the customer tries to use the Test Object again and the test fails since the Test Object doesn’t have a description or a runtime ID.

The problem is that QuickTest creates a layer of abstraction above the application being tested and like all sufficiently powerful abstractions it’s leaky. We know what ChildObject does and we know what Exist does but put them together and BOOM the things you don’t know (or weren’t supposed to know like runtime ID) come leaking through and punch you in the face.

Our solution was to have Exist always return true when run on a Test Object that has a runtime ID but no description, we feel that this is correct behaviour since you just got the object from the application using ChildObject, obviously it Exists otherwise it wouldn’t have been returned.

An alternative solution could have been to make the objects returned from ChildObject create their description, however that would slow down all tests that use ChildObject for the benefit of the vanishingly small number of tests that check for existence.

The best way to avoid the problem in the first place is to use objects created by ChildObject as soon as they are created and before anything changes in the application being tested.





1K answer

27 09 2017

Today my most up-voted stackoverflow answer reached the 1K upvote mark.

screenshot of question

If all I had ever done in stackoverflow was to answer this one question[1] I would be in the top 4% of users.

I’m not sure how this makes me feel… In the beginning stackoverflow was a magical place were your questions were instantly answered and one could find questions to answer just by going to the front page.

Now just going to the front page looking for an interesting question to answer is usually a futile experience. As a result, getting involved in stackoverflow now (and gaining enough reputation in order to do meaningful things), is getting progressively harder. Just recently a co-worker contacted me in order to help create a tag for one of our products since nobody in their department had enough reputation to do so.

More and more I hear anti-stackoverflow sentiments, people complain about their questions being closed for insufficient reasons and that the standards of answers are declining.

I hope that the stackoverflow team are able to keep the site relevant and useful while coping with the curse of too much(?) success.


1. Not to mention the fact that I don’t think this question still belongs in stackoverflow, it’s not really programming related and would be a better fit for superuser.com (which didn’t exist when the question was asked) 




The code/data duality

6 01 2016

One often wants special code to run the first time a function is invoked. In C++ the naïve way to do this is using function-static variables.

Consider a function that returns a random number. For nostalgia’s sake we want to use rand  (which needs to be seeded via srand before the first use). We may do something like this:

#include <cstdlib>

int random(int max) {

       static bool initalized = false;

       if (!initialized) {

              srand(time(nullptr)); // seed the random generator once

              initialzed = true;

       }

       return rand() % (max+1);

}

When I was in university, towards the end of the previous millennium, we had to learn VAX assembly (not the most useful skill I’ve ever picked up). That was when I was introduced to the concept of self modifying code. The crux of the matter is pretty obvious in hindsight, code and data aren’t different things, in the end everything is software is bits and bytes. This means that we can modify the code of the program as simply as modifying variables.

I don’t remember my assembly and I’m assuming that anyone reading this either:

  1. Doesn’t know/remember assembly
  2. Doesn’t need me to explain about code re-writing

So I’ll just invent a simple stack based assembly language since I can’t be arsed to re-learn assembly.

If we take the random function above and translate it to pseudo-assembly we would get something like:

# randomInitialized
0x000DAF00:  0x0  # initialized to zero at compile time
# random
0x000DAF04loadAddress randomInitialized
0x000DAF08branchNotZero randomInitizliedmainFlow
0x000DAF0Cload 0 # first run
0x000DAF10call time
0x000DAF14load 1
0x000DAF18storeAddress randomInitialized
0x000DAF1Ccall srand
# mainFlow
0x000DAF20: increment # max is currently on the stack
0x000DAF24: call rand
0x000DAF28: modulo # rand() % max + 1
0x000DAF2C: return

This is pretty straight forward mapping of the C[++] code to assembly and it has the same drawbacks. We perform a comparison every time the function is run (!initialized) although it almost always has the same outcome. Another deficiency of the code is more pronounced in the assembly version, a lot of code is skipped over for most calls which works against the instruction cache.

What we would really want is that every time the function is called, except for the first time, it will just do what it needs to be done. This can be achieved by modifying the code.

We compile the function to start with a jump (aka goto) to some address (outside the function) which calls srand and then replaces the jump with the first instruction we want for the subsequent function calls. The first instruction we want is  increment, for the sake of argument we’ll say that the opcode for increment is  0xADD1.

# initializeRandom
0x000DAF00load 0
0x000DAF04call time
0x000DAF08call srand
0x000DAF0Cload 0xADD1 # opcode(increment)
0x000DAF10storeAddress random
random
0x000DAF14: jump initializeRandom
0x000DAF18: call rand
0x000DAF1C: modulo # rand() % max + 1
0x000DAF20: return

During the first run the first thing we do is jump out to a memory location that precedes the function proper, then we seed the random number generator and modify the beginning of the function from being a jump to being an increment1. The initial jump is computed in advance so that we store the increment  just after the instruction pointer and then just fall through into the (now) modified function. Subsequent calls to the
function have a lean four instruction function to execute with no conditions and no branches.

random
0x00DAF14: increment # this is now the first opcode
0x00DAF18: call rand
0x00DAF1C: modulo # rand() % max + 1
0x00DAF20: return

There’s no need to waste space on a static variable, the code is more cache friendly and (at least in my made up assembly) smaller.

So if everything is so good why isn’t this used in practice? OK so high level languages don’t give you direct access to the code parts of your program but the compiler could generate such code, right?

Well I understand next to nothing about compilers but I’m pretty sure that multiple cache levels at least will make things unpractical (not to mention branch prediction).

The most obvious problem with this example is that it’s horrendously thread unsafe.  I suppose that some of the readers have been tearing out their hair from the get go, the original C++ function with the static variable was just as unsafe. An unprotected shared variable could be modified different threads simultaneously which is a data race and undefined behavior (starting with C++11).

As an aside I would like to mention that C++11 introduced “thread-safe function local static initialization”  so a better implementation of random would be:

#include <cstdlib>
int random(int max) {        
    static bool unused = ([]{// define and invoke a lambda that
        srand(time(nullptr)); // seeds the random generator
        return false;
    })();

    return rand() % (max+1);
}

Here I’m depending on the fact that a it’s the compiler’s responsibility to initialize a static variable is only once in a thread safe way. The static variable here is a bool but it’s never really used, all we need is the side effect when creating it (does anyone what to submit a proposal to allow static void variables?).

In most mainstream compiled languages, the code doesn’t have access to the generated machine code. Thus most programmers nowadays have a mental divide between code and data (Lisp programmers, feel free to gloat now). However JavaScript, as a scripting language  with a functional orientation, brings the code/data duality back together again.
Since functions (code) are objects, self mutating code is back in business. Luck would have it that JavaScript is single threaded (mostly) which allows code to mutate in a thread-safe way.

Consider, for example, a wrapper around a WebSocket.
After creating a web-socket it’s not usable until the connection is established. Due to the single threaded nature of JavaScript this means that you have to relinquish control of the thread before using the object. Say we want to store all outgoing messages until the socket is opened and then send them, one way to achieve this would be like this:

function Socket(address) {
    this.socket = new WebSocket(address);
    
    var queue = []; // captured by 'send' and 'onopen'
    this.send = function (message) {
        if (this.socket.readyState !== WebSocket.OPEN)
            queue.push(message);
        else
            this.socket.send(message);
    }
 
    this.socket.onopen = function () {
        // send queued messages
        queue.forEach(msg => this.send(msg));
    };
}

Now let’s see how the same thing could be achieved with self modifying
code:

function Socket(address) {
    this.socket = new WebSocket(address);
 
    var queue = []; // captured by 'send' and 'onopen'
    this.send = message => queue.push(message);
 
    var self = this;
    this.socket.onopen = function () {
        // send queued messages
        queue.forEach(msg => this.send(msg));
        // replace the 'send' message
        self.send = function (message) {
            this.socket.send(message);
        };
    };
}

The send function now has two instances, before the socket is fully open
and after it is open. But wait, what about after the socket is closed? For some reason sending on a closed socket outputs an error to the console but does not throw an exception. We can modify this behaviour like this:

this.socket.onclose = function () {
    // replace the 'send' function yet again
    self.send = message => {
       throw Error('Sending on closed socket: ' + message);
    }
};

Now we see that code is can be more complex than having two different states, it can be a fully fledged state machine. Admittedly, for most code it is a state machine with only one state, no input to the code modifies the code itself. However it may be useful to keep in mind that the code itself can model the problem space in addition to the data and data structures.


1. In real life the instructions aren’t necessarily the same length but you get the idea




Work blog post – Container objects in UFT

5 11 2015

As both my regular readers have probably noticed (hi Mum! [who am I kidding, even my mother doesn’t read this]) the frequency of my posts have gone down from about once a month in the beginning to closer to twice a year. This is a combination of not having anything interesting to say and life not leaving me with much time to say uninteresting stuff.

Well at work they have funny standards to what can be considered interesting and one such subject is adding container test objects to web tests in UFT.

image from the post

It even has images!

This feature was actually implemented in UFT 12.02 (released last year) but there wasn’t enough time to sufficiently QA it and therefore the feature was undocumented and only used by a few beta customers. Starting with UFT 12.50 it’s finally an official, documented feature which is the first step to benefiting our customers. Step two is to have someone actually use it which is were the blog post comes in…





Visual Studio debuger visualizer for JsonCPP

6 06 2015

We’ve been working with the JsonCPP library and while it’s very nice to use, it’s a bit of a pain to debug. For example consider this simple JSON value:

var json = [ 
  42, 
  { 
    "name": "hello", 
    "pi": 3.1415926, 
    "valid": true 
  }
]

If you want to see the value of the pi in the debugger it would look (after some digging) something like this:

JSON with no visualizer

After enduring this for a bit too long I decided to look for a debuger visualizer for JsonCPP but couldn’t find one. So as a last resort I decided to write one myself. I have to say that I was pleasantly surprised to find that this was pretty simple and after a little work I got to the situation that my debugger window looked much more manageable:

JSON with visualizerIf you want to use this visualizer you can find it at in GitHub’s visualstudio-debugger repository.





Cactus shirt

17 05 2015

This is the second post in my shirts series, in my first post I told about the hobby I had twenty years ago, drawing on shirts. Since they have started falling to pieces and I can’t make myself throw them out I decided to write about them so that they can live on in digital form and I can reclaim some wardrobe space.

This is one of my first shirts so there are a few unforced errors which I attempted to cover up.

The Front

Cactus-front

On the front I have my Abrahamic character drinking from a decapitated cactus with the caption “Enjoy Cactus Cola, the Sheik’s thing”. This is a play on Coca Cola’s slogan and the similarity between Sheik and Chic. Since this is a cactus the sheik’s hand is obviously bleeding. One of the reasons I’ve stopped wearing this shirt at home is that my children find the blood very disturbing and can’t help but comment about it whenever they see the shirt.

I then got a stain in the centre of the shirt and had to cover it up, I chose a skull and crossbones with the warning

Use of this product may prove hazardous to haemophiliacs

The Back

 Cactus-back

The back of the shirt is a bit of a hodgepodge of desert-based jokes.

I have the character from the front of the shirt crawling towards a mirage. You’ll notice that he has a star and crescent armband, this is to cover up my second error where I initially draw the arm as some kind of Möbius strip.

Next to the mirage is the skeleton of a fish (complete with the skeleton of bubbles coming out of its mouth). The idea was that the fish came to live in the mirage and died since there wasn’t really any water there (what can I say I thought it was amusing at the time).

The sun is wearing sunglasses as is its wont and drinking from a can of Mercury with a straw (mercury being both a liquid and a celestial body). The can of mercury is labelled with both its astrological and chemical symbol, I should note that this was before I heard of the Mercury company I later worked for.

Next to that is the skeleton of Joe Camel who died of lung cancer (I thought that was edgy at the time) and a dog gnawing on one of its bones.

And to complete the plethora of pathetic puns are the Cacti family with the Mother cactus, father cactus and their son showing off his muscles.