IMPORTANT - Adjust object names for objects with changeable texts early

Last edited on

Introduction

Consider the following application window and its title "Address Book":

When clicking the New tool button on the left, the window title changes to "Address Book - Unnamed":

When recording this mouse click on the tool button in a new test suite for the first time, a script similar to the following will be recorded:

import names

def main():
    startApplication("addressbook")
    clickButton(waitForObject(names.address_Book_New_QToolButton))

The resulting object names in the object map are shown here:

This tells us that a button in a window with the title "Address Book" was interacted with.

When recording a new test, but this time clicking the New tool button on the left twice, the resulting test script looks like this:

import names

def main():
    startApplication("addressbook")
    clickButton(waitForObject(names.address_Book_New_QToolButton))
    clickButton(waitForObject(names.address_Book_Unnamed_New_QToolButton))

And the resulting object names in the object map are:

As you can see, even though the recording was performed for two separate clicks on exactly the same toolbar button, Squish identifies the button with different object names for the first and the second click, simply because the containing window object changed its title. (Squish must make such distinctions because each click occurs when the application is in a different state. In this example, for the first click the application has no addressbook data, but for the second click the application has an empty addressbook of data.)

As you can imagine, if your windows keep changing their titles, you will get more and more very similar object names all referring to the same object (e.g., to the same button). This isn't a problem for Squish, and is useful as the application's state changes. However, if we know that a button is the same no matter what the application's state (e.g., the Addressbook application's New toolbar button never changes), we can use this knowledge to simplify things and to use a single name rather than lots of different ones. Using a single name can help make test scripts more robust in the face of changes, so it is well worth doing for names which depend on changeable window titles or other volatile text.

After recording a test, if you notice that there is volatile text, it is worth looking at the Object Map to see if any of the names are affected by this text. If there are, it is best to edit the affected names in the Object Map. For example, you could make an object's windowTitle property use wildcards or regular expressions to ensure it matches the window title even if the window title changes.

Here is an example of the above object name for the window being adjusted to use wildcards:

From now on Squish will keep using this object name (as long as it matches the window's title) and not create new object names for the same objects (buttons, etc.) again.

Removing Changeable Parts from Symbolic Names

Suppose that we have an Object Map entry like this:

Symbolic NameReal Name
names.MyApp_V1_0_MainWindow
{"type": "MainWindow", "windowTitle": Wildcard("MyApp V*")}

Here, we have used a wildcard match in the real name. This means that when Squish looks for an object with the symbolic name names.MyApp_V1_0_MainWindow, it will find the first object whose type is MainWindow and whose windowTitle property begins with the text "MyApp V" (e.g., "My App V1", "My App V2.5", etc.).

It seems a pity to keep the version number in the symbolic name since that could cause confusion later on (e.g., when the application is at version 2). This is easy to solve by changing the symbolic name in the Object Map --- and, of course, we must also change it in any test scripts that are using it. For example:

Symbolic NameReal Name
names.MyApp_MainWindow
{"type": "MainWindow", "windowTitle": Wildcard("MyApp V*")}

Alternative Solution

An alternative solution can sometimes be to just remove a real name's container or window property. This will make Squish look for the object in all available windows or containers.

Note however that some types of objects are not searched for in every possible container, such as items in tables or models. So, for example, when it comes to QModelIndex objects, the container property must be kept for Squish to be able to find the item.