|User Guide / Interface definitions|
Any action line that interacts with an AUT has one or more arguments that specify a window or control. Generally, we populate these arguments with static identifiers, which you know better as TA names, and which are created in the form of interface entities and their constituent interface elements.
Static identifiers have set values, established in interface entities before your test is run. The problem is, there may be times when you want your test procedure to control which UI element a given action is directed at. You can accomplish this with dynamic identifiers.
The static identifiers created by interface elements are useful for application windows that have a consistent appearance in terms of the controls that populate them, and the properties of those controls (or at least the properties that are used for mapping). They fall short, however, when it comes to mapping controls or elements that are dynamically created by an AUT.
To compound the problem, such controls are often created in amounts that cannot be known in advance. A typical example is a search on a web page that presents its matches with hyperlinks. The better alternative is to use dynamic identifiers, in which you explicitly specify the class of the control and the values of identifying properties within the actual action lines of a test module or action.
[ta class=<ta class name>, <TA property name 1>=<property value>, <TA property name 2>=<property value>,...]
You can use a dynamic identifier wherever you use a logical TA name. As an example, take
the following (conventional) login action for the Car
Rental application, whose static identifiers are defined in the interface entity
The following action, which uses dynamic identifiers to identify the controls, functions in
an identical manner:
Note that, on line 18 in this revised action, we replace only the control argument with a dynamic identifier (simply to show that static and dynamic identifiers can live side-by-side on the same action line). Line 22 demonstrates that both the window and control arguments may be hold dynamic identifiers. Note also that, as mentioned earlier, window dynamic identifiers require only a set of property-value pairs (one is usually sufficient), while a dynamic identifier for a control also requires that the TA class of the control be identified.
So, we've established that dynamic identifiers are great for people who are too lazy to create interface entities. But what else are they good for?
One way in which the power of dynamic identifiers can be exploited is in the fact that they can be constructed "on the fly" by means of expressions. In particular, concatenation expressions that include variables can be very useful.
As an example, the following test case uses a variable-based dynamic identifier to cycle
through global pos values. The outcome
of the procedure is a report of the number of buttons in an AUT window, which the test is
able to perform without knowing anything about those buttons (that is, no identifying
property values), aside from the fact that they all have a TA class of
See also Using anchor pos with dynamic identifiers for an example of dynamic identifiers and expressions.
A multilevel dynamic identifier is one in which the value setting for a TA property is itself a dynamic identifier. In turn, that inner dynamic identifier may also have a TA property defined by a dynamic identifier, and this can go on for any number of levels.
Most typically, it is a control's anchor pos that is used as the operational property in a multilevel dynamic identifier, as the nature of anchor pos lends itself to the identification of controls through multiple levels of a window's control hierarchy.
[ta class=panel, anchor=lv2, anchor pos=panel 2]
[ta class=panel, anchor=[ta class=panel, anchor=lv3, anchor pos=panel 1], anchor pos=panel 2]
[ta class=panel, anchor=[ta class=panel, anchor=[ta class=panel, anchor=[ta class=root pane, global pos=root pane 1], anchor pos=panel 5], anchor pos=panel 1], anchor pos=panel 2]
From the standpoint of readability, a good practice
is to assign each inner level of a multilevel dynamic identifier value to a variable, and
then construct the full identifier in the control argument of the
action that must reference
For example, instead of using a two level dynamic identifier in an action line, such as
you might prefer the clarity that comes with decomposing that complex action line into the following, which is functionally equivalent: