Name

In case the developers have assigned Component identifiers to a component, QF-Test will recognize this and use it, if suitable, for the attribute 'Name'.

If a value for 'Name' was found, it will also be used for generating the 'QF-Test ID' of the component. Examples for this can be found in How to achieve robust component recognition.

The value of the 'Name' attribute is also the first choice during recording of SmartID (Preview)s.

The reason for the tremendous impact of names is the fact that they make component recognition reliable over time. Obviously, locating a component that has a unique name assigned is trivial. Without the help of a name, QF-Test uses lots of different kinds of information to locate a component. The algorithm is fault-tolerant and configurable and has been fine-tuned with excellent results. However, every other kind of information besides the name is subject to change as the SUT evolves. At some time, when the changes are significant or small changes have accumulated, component recognition will fail and manual intervention will be required to update the test suite.

Another aspect of names is that they make testing of multi-lingual applications independent of the current language because the name is internal to the application and does not need to be translated.

Test automation can be improved tremendously if the developers of the SUT have either planned ahead or are willing to help by defining names for at least some of the components of the SUT. Such names have two effects: They make it easier for QF-Test to locate components even after significant changes were made to the SUT and they are highly visible in the test suite because they serve as the basis for the 'QF-Test IDs' QF-Test assigns to components. The latter should not be underestimated, especially for components without inherent features like text fields. Nodes that insert text into components called "textName", "textAddress" or "textAccount" are far more readable and maintainable than similar nodes for "text", "text2" or "text3". Indeed, coordinated naming of components is one of the most important factors for the efficiency of test automation and the return of investment on QF-Test. If development or management is reluctant to spend the little effort required to set names, please try to have them read this chapter of the manual.

If developers used another consistent scheme for assigning identifiers which QF-Test does not recognize out of the box, please take a look at Influencing the 'Name' attribute by implementing a NameResolver.

When determining distinct 'Names', the options Name override mode (replay) and Name override mode (record) can be set to "Override everything", which makes the component recognition independent from the component hierarchy. Because of name caching, this will gain maximum performance.

To simplify assigning of identifiers, QF-Test offers a feature to suggest identifiers for components whose testing would benefit from it. Read more about this in Hotkey for components.

Note Changes to identifiers in the application under test should be avoided as much as possible, as this undermines component recognition and can mean a lot of rework in the tests. Please note that if changes do occur, they should be made in the 'Name' attribute of the component and not in the 'QF-Test ID' attribute, which is only used to reference the component in the tests! Another possible difficulty can be that the name change occurs directly in the test in the reference to the component, for example when a mouse click occurs in the 'QF-Test component ID' attribute. The test then fails with an UnresolvedComponentIdException.

Component identifiers

Component identifiers are called differently in the different UI technologies. In the manual, the term 'name' is also used for them. In addition, the criteria for whether and how the identifiers are transferred to the 'name' attribute are slightly different depending on the technology.

The following is valid for the default settings, especially of Name override mode (replay) and Name override mode (record) (default value: "Hierarchical resolution"). The use of resolvers could change the described behavior as well.

Java Swing/AWT

The component identifier is called 'Name' here. If set, it will be transferred to the 'Name' attribute. If there are duplicate component identifiers inside a container, QF-Test will create the 'Extra feature'qfs:matchindex with the appropriate index for the duplicates.

All AWT and Swing components are derived from the AWT class Component. That is why their setName method is the standard for Swing SUTs. Thanks to this standard, many developers make use of it even without considering test automation, which is a great help.

JavaFX

The component identifier is called 'ID', here. If set, it will be transferred to the 'Name' attribute. If there are duplicate component identifiers inside a container, QF-Test will create the 'Extra feature'qfs:matchindex with the appropriate index for the duplicates.

For JavaFX, setId is used to assign names to components (here called "nodes"). Alternatively, IDs can be set in FXML via the attribute fx:id. Although IDs of nodes are supposed to be unique, this is not enforced.

Java SWT

The component identifier is also called 'Name', here. If set, it will be transferred to the 'Name' attribute. If there are duplicate component identifiers inside a container, QF-Test will create the 'Extra feature'qfs:matchindex with the appropriate index for the duplicates.

Unfortunately SWT has no inherent concept for naming components. An accepted standard convention is to use the method setData(String key, Object value) with the String "name" as the key and the designated name as the value. If present, QF-Test will retrieve that data and use it as the name for the component. Obviously, with no default naming standard, very few SWT applications today have names in place, including Eclipse itself. Fortunately QF-Test can derive names for the major components of Eclipse/RCP based applications from the underlying models with good results - provided that IDs were specified for those models. See the Automatic component names for Eclipse/RCP applications option for more details.

Web

The natural candidate for naming the DOM nodes of a web application is the 'id' attribute of a DOM node - not to be confused with the 'QF-Test ID' attribute of QF-Test's 'Component' nodes. Unfortunately the HTML standard does not enforce IDs to be unique. Besides, 'id' attributes are a double-edged sword because they can play a major role in the internal JavaScript operations of a web application. Thus there is a good chance that 'id' attributes are defined, but they cannot be defined as freely as the names in a Swing, JavaFX or SWT application. Worse, many DHTML and Ajax frameworks need to generate 'id' attributes automatically, which can make them unsuited for naming. The option Turn 'ID' attribute into name where "unique enough" determines whether QF-Test uses 'id' attributes as names.

Fortunately, component identifiers can be realized via different attributes of the GUI element. Mostly it is the attribute 'id', sometimes also 'name' - but other attributes can be used as well.

The option Turn 'ID' attribute into name where "unique enough" determines whether QF-Test uses 'id' attributes for names or not. Please keep in mind that the option Eliminate all numerals from 'ID' attributes can also cause originally unique identifiers to not be unique anymore after the deletion of the numbers. When checking if the resolved 'Name' is unique, the component's parent containers will be considered when judging uniqueness if the options Name override mode (replay) and Name override mode (record) are set to the default value "Hierarchical resolution".

The automatically generated 'id' attributes sometimes contain a static part which can be used as identifier. This can be configured through the CWR parameter autoIdPatterns, see installCustomWebResolver - Parameters. Also, this procedure can be used with the customIdAttributes parameter to use any other HTML attribute as a component identifier.

In case of web applications that use a UI toolkit supported by QF-Test, you can look at subsection 47.2.2 to learn more about setting unique identifiers for each toolkit.

Win
The component identifier is called 'AutomationId' here. If set, it will be transferred to the 'Name' attribute. If there are duplicate component identifiers inside a container, QF-Test will create an 'Extra feature' named qfs:matchindex and an appropriate index for the duplicates.
Android
The component identifier is called 'ID', here. It will only be transferred to the 'Name' attribute if it is not a trivial class name (see Android - list of trivial component identifiers). If there are duplicate component identifiers inside a container, QF-Test will create the 'Extra feature'qfs:matchindex with the appropriate value for the duplicates.
About setting identifiers

There is one critical requirement for identifiers: They must not change over time, not from one version of the SUT to another, not from one invocation of the SUT to the next and not while the SUT executes, for example when a component is destroyed and later created anew. Once an identifier is set it must be persistent. Unfortunately there is no scheme for setting identifiers automatically that fulfills this requirement. Such schemes typically create identifiers based on the class of a component and an incrementing counter and invariably fail because the result depends on the order of creation of the components. Because identifiers play such a central role in component identification, non-persistent identifiers, specifically automatically generated ones, can cause a lot of trouble. If development cannot be convinced to replace them with a consistent scheme or at least drop them, such identifiers can be suppressed with the help of a NameResolver as described in subsection 50.1.6.

QF-Test does not require ubiquitous use of identifiers. In fact, over-generous use can even be counter-productive because QF-Test also has a concept for components being "interesting" or not. Components that are not considered interesting are abstracted away so they can cause no problem if they change. Typical examples for such components are panels used solely for layout. If a component has a non-trivial identifier QF-Test will always consider it interesting, so naming trivial components can cause failures if they are removed from the component hierarchy in a later version.

Global uniqueness of identifiers is also not required. Each class of components has its own namespace, so there is no conflict if a button and a text field have the same identifier. Besides, only the identifiers of components contained within the same window should be unique because this gives the highest tolerance to change. If your component identifiers are unique on a per-window basis, set the options Name override mode (replay) and Name override mode (record) to "Override everything". If identifiers are not unique per window but identically named components are at least located inside differently named ancestors, "Hierarchical resolution" is the next best choice for those options.

Two questions remain: Which components should have identifiers assigned and which identifiers to use? As a rule of thumb, all components that a user directly interacts with should have an identifier, for example buttons, menus, text fields, etc. Components that are not created directly, but are automatically generated as children of complex components don't need an identifier, for example the scroll bars of a JScrollPane, or the list of a JComboBox. The component itself should have an identifier, however.

If components were not named in the first place and development is only willing to spend as little effort as possible to assign identifiers to help with test automation, a good strategy is to assign identifiers to windows, complex components like trees and tables, and to panels that comprise a number of components representing a kind of form. As long as the structure and geometry of the components within such forms is relatively consistent, this will result in a good compromise for component recognition and useful 'QF-Test ID' attributes. Individual components causing trouble due to changing attributes can either be named by development when identified or taken care of with a NameResolver.

Influencing the 'Name' attribute by implementing a NameResolver

In GUI testing projects you can face a lot of interesting naming concepts. Sometimes the components in an application have no names, but the testers know an algorithm how to name them reliably. Sometimes existing names change from time to time or are completely dynamic, for example you can get a name 'button1' after the first recording and after the second recording you get 'button2'. Another situation could be that the current version of the application is part of the name of a dialog window.

Sometimes the tester knows an algorithm for setting unique Namen. In such cases you should take a closer look at The NameResolver Interface in the chapter The resolvers module.

A NameResolver can be used to change or remove names set by developers for the QF-Test perspective. They are only removed for QF-Test not from the real source code.

You can think about utilizing NameResolvers in following cases:

  • The SUT has dynamically changing names.
  • You know a method to set the names uniquely.
  • You want to map names to other names (for example due to new versions or for testing other languages.)
  • You want to tune the names of components, for example to remove some parts and get nicer QF-Test component IDs in QF-Test.

If you can achieve per-window uniqueness of names with the help of a NameResolver you can also think about setting the options Name override mode (replay) and Name override mode (record) to "Override everything".

Note Whenever possible it is preferable that developers set the names directly in their source code as they best know the context of that component. Implementing a NameResolver can become an excruciating task if the developers change the content of the GUI a lot.

NameResolvers are described in detail in subsection 50.1.6.