HPE Software is now Micro Focus
HPE Software is now Micro Focus
Quality and Testing Blog
cancel

Improve your Unified Functional Testing web tests by adding Container Objects

Improve your Unified Functional Testing web tests by adding Container Objects

OriBendet

 

(This post was written by Motti Lanzkron from the HPE UFT R&D Team)

 

Back in 2013 I wrote about the “web test object model in UFT”, in which I said:

 

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

There’s good reason for Hewlett Packard Enterprise Unified Functional Testing (UFT) automated testing to flatten the hierarchy (as the post elaborates) and it is still mostly true. However beginning with UFT 12.50 we’ve added the capability to enable UFT to add another level in the test object hierarchy.

 

Glossary: we’ll call an object that adds a level in the hierarchy a container object since it contains other test objects.

 

The motivation for this is to allow you, the test engineer, to add logical grouping to your web test objects. This has two advantages:

  • Improved test maintainability and readability – The objects are now easier to find in the object repository and neighboring objects in the application will be located closer in the object repository.
  • Increased test robustness – Since the description is relative to the test object’s parent, we’re less likely to need to resort to using assistive properties or ordinal identifiers to identify an object (as mentioned in the aforementioned post).

This ability isn’t added to the built-in web test objects. Instead it is meant for Web Extensibility developers to provide better support for their application since they (you) are the people best qualified to know what constitutes a logical partition of the web page.

Now don’t be scared by this being Web Extensibility. It’s quite simple to create a new control that helps partition your page. This post shows how it can be done.

 

Executive summary: add IsContainer="true" to your extensibility object

 

Any Web Extensibility object can be a container and the first thing to decide is what functionality we want this object to have. In some cases the container object has no independent functionality and its only purpose is to group any other objects. For simplicity, this is the assumption we will make. (However keep in mind that these container objects are fully fledged test objects and can contain operations and properties if it makes sense for them to do so.)

 

Example

We’ll use reddit’s login dialog as an example.

 

 

The login dialog is made up of three areas:

  • Sign up – For people who don’t yet have an account
  • Log in – For people who already have an account
  • General – Stuff that isn’t specific to either of the previous categories

If we learn the objects on this page we will get the following test objects object repository:

 

 

There are several problems with this Object Repository:

  • You can see that we’re using ordinal identifiers for the user edit field. This makes the test less robust since the index of an element may change due to simple UI changes in the application even if the functionality hasn’t changed (for example if Log in is moved to the left of Create a new account).
  • It’s hard to know which element a test object refers to (user vs. user_2).
  • Test objects that are adjacent in the Object Repository are not necessarily related or close together in the actual web application.

Web Extensibility allows us to define new test objects and map HTML elements to them. We’ll take advantage of the FORM element pictured here.

 

 

Usually UFT ignores FORM elements since UFT simulates real user actions and people don’t directly interact with forms. However, we’ll define a simple test object called EgForm which will be used for the logical grouping of the test objects it contains.

After implementing EgForm we will get the following Object Repository which contains two EgForm objects, one called login and the other called register:

 

Here we can see that the Object Repository’s contents reflect the layout and functionality of the site. Objects are easier to find and the description doesn’t rely on ordinal identifiers.

The advantages of the second Object Repository are a bit more obvious when you colour code each test object according to the location of the test object in the site.

 

The same hierarchy is generated both by the learn feature and recording.

 

 

Implementation

Here we’ll learn how to create a simple extensibility project called “Example” which can then be loaded in the Add-In Manager:

 

 

You can see the entire implementation here, just extract the zip file into UFT’s installation directory.

 

We define a new test object by defining a test object XML and placing it under UFT’s installation directory in in dat\Extensibility\Web (this XML is based on the schema in dat\ClassDefinitions.xsd). For more information see the UFT Test Object Schema topic in help\Extensibility\WebExtensibility.chm.

 

Defining the Test Object

The first thing we need to do is describe the test objects we’ll be creating. In this case we’re only introducing a single test object.

<TypeInformation PackageName="Example" AddinName="Web">

  <ClassInfo Name="EgForm" BaseClassInfoName="WebElement">

    <IdentificationProperties>

      <IdentificationProperty Name="html idForDescription="true"  />

      <IdentificationProperty Name="html tag" ForDescription="true" />

    </IdentificationProperties>

  </ClassInfo>

</TypeInformation>

 

There’s nothing much in this file - a test object called EgForm with two identification properties. html tag since it’s always good practice to have the tag name in the description if possible and the html id. The ID of an element is often not a good candidate for description because there are many sites that generate new IDs every time the site is loaded—but for the reddit example it’s a good identifier.

 

Identifying the new control

The toolkit XML is placed in a new folder under dat\Extensibility\Web\Toolkits and is based on the Toolkit.xsd schema which can be found there:

<Controls>

  <Control TestObjectClass="EgForm" IsContainer="true">

    <Identification>

      <Browser name="*">

        <HTMLTags>

          <Tag name="FORM" />

        </HTMLTags>

        <Conditions type="IdentifyIfPropMatch">

          <Condition prop_name="idexpected_value=".+" is_reg_exp="true" />

        </Conditions>

      </Browser>

    </Identification>

    <Settings>

      <Variable name="default_imp_file" value="JavaScript\EgForm.js"/>

    </Settings>

  </Control>

</Controls>

 

The most important thing in this file (in the context of this post) is where it says IsContainer="true".  Once an object is designated to be a container it will automatically contain all the objects which are nested underneath it in the application’s HTML.

The rest of the file says that this works for all supported browsers and that we want to identify FORM elements who have a non-empty ID.

 

We also specify a JavaScript file (default_imp_file), we could do without it—but I wanted our forms to have a nice name and not all be called EgForm.

 

Implementing the new control

The implementation of any new Web Extensibility test object is done in JavaScript, in our case we don’t want to introduce any new functionality such as recording or new functions.

All we want to do is override the default name of the test objects we’re creating. This is done by implementing a function called get_property_value which UFT uses in order to get the values of a Web-Extensibility object’s properties.

 

function get_property_value(name) {

    switch (name) {

        case 'logical_name':

            return _elem.id.replace(/-form$/, '');

    }

}

UFT uses logical_name in order to determine the name to use in the Object Repository, here we return the ID after removing any trailing -form (again this is what works for this example, pick what works for your application).

 

Some guidelines

Note the following when using this:

  • When recording or learning an object all its container ancestors will be added to the Object Repository. As a result, make sure that you don’t add redundant levels into the object hierarchy.
  • Often the rule for matching a container may match multiple HTML elements which represent the same logical container. Therefore make sure your rules are exclusive enough to prevent matching multiple objects when only one is expected.
  • Keep in mind that excessively deep object hierarchies present their own problems, only add containers when it makes sense to do so.

Try it Out

Please go ahead and try out this new feature in UFT, I’m sure you’ll find it useful.

The source code used in this example is available in this zip file, just extract it under UFT’s installation folder and select the Example add-in in the Add-In Manager. You can also find the two SORs shown in this post.

 

Thanks to Motti for providing this article!

 

Try Unified Functional Testing for yourself!

 

Feel free to leave a comment in the box below.

 

 

Ori Bendet, Functional Architect
  • Future of Testing
0 Kudos
About the Author

OriBendet

Functional Architect, FT

Attachments