Version 8.0.1 |
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 SmartIDs.
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 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.
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.
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.
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.
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 Use ID attribute as name 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 Use ID attribute as name 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 category autoIdPatterns
, see
'Install CustomWebResolver' node – Syntax.
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 50.2.2 to learn more about setting unique identifiers for each toolkit.
qfs:matchindex
and an appropriate index for the duplicates.
qfs:matchindex
with the appropriate value for the duplicates.
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 53.1.7.
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
.
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:
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 53.1.7.
Last update: 9/10/2024 Copyright © 1999-2024 Quality First Software GmbH |