Troubleshooting component recognition problems

Timing synchronisation

If you get exceptions because a component was not found, one of the reasons may be that you did not wait for the component long enough. A mouse click has a certain default waiting time, but this is not always sufficient. Therefore you should check if there are enough synchronization points, like 'Wait for component to appear' or 'Check' nodes with waiting times to only execute the test steps if the SUT is really ready for it.

  • A 'Wait for component to appear' node can be used when a new component appears. The maximum wait time (in milliseconds) is set in 'Timeout'.
  • A 'Check' node is used to wait for a state change of components. The maximum wait time (in milliseconds) is set in 'Timeout' here as well.
  • Sometimes it is also necessary to loop, waiting for the state change and, if not already done, performing an action, for example, clicking a "Refresh" button.
  • You can also wait for the number of rows in a table to change in a loop.
  • Many applications use indicators that symbolize waiting times, for example progress bars or "egg timers". Here you can wait first for the component to appear and then for it to disappear.

The maximum wait time is set in the 'Timeout' attributes. As soon as the desired application state is reached, QF-Test continues execution. These waiting times can therefore be chosen generously.

You should only change the option for default waiting times (subsection 37.3.6) if generally longer waiting times make sense across your whole application.

Note As a last resort you can also use with a fixed delay. When the attribute 'Delay before/after' is set, QF-Test will wait the entire given time. 'Delay before/after' should therefore only be used if there is no state change detectable by QF-Test in the application which QF-Test could wait for.

Recognition

If your SUT changes in a way that makes it impossible for QF-Test to find a component again, your test will fail with a ComponentNotFoundException. This should not be confused with an UnresolvedComponentIdException, which can be caused by removing a 'Component' node from the test suite or by changing the attribute 'QF-Test component ID' of an 'Event' node to a non-existing 'QF-Test ID'.

Video There are two videos that comprehensively explain how to handle a ComponentNotFoundException:

When run into an ComponentNotFoundException, run the test again with the test debugger enabled so that the test stops and you can examine the node that caused the problem. This is where it pays to have 'QF-Test ID' attributes that are meaningful, because you need to understand which component the test was trying to address. If you can't make any sense of what the node in question is supposed to be, disable it and see if the test goes through without it. It could be a spurious effect that was not filtered during the recording and that does not contribute anything to the actual test. Basically, your tests should always be reduced to the minimum number of nodes that can be used to achieve the desired effect.

If the node must be preserved, next take a look at the SUT to see if the target component is currently visible. If not, you will need to adjust your test accordingly to handle this situation. If the component is visible, use the screenshot in the log to verify that this was the case at the time of the failure and try executing the failed node again as a single step. If execution now works you have a timing problem which you can solve by including a 'Wait for component to appear' node, a 'Check' node with 'Timeout', or another waiting action (see Timing synchronisation).

If the component is visible and the replay continuously fails, the reason is a change in the component or one of its parents. Now you must determine what changed and where. For this, record a new click on the component and compare the new and old 'Component' node in the hierarchy below 'Windows and components'.

Note You can jump directly from the 'Event' node to the associated 'Component' by pressing [Ctrl-W] or by selecting »Find component« from the context menu. You can use [Ctrl-Backspace] or »Edit«-»Select previous node« to jump back again. A smart move is to denote the 'Components' to be compared using markers with »Edit«-»Mark« to easily find them again.

The crux is where the hierarchy of the two nodes branches. If they are located under different 'Window' nodes, the difference is in the respective 'Windows' themselves. Otherwise, there is a common predecessor just above the branch. The crucial difference is then found in the respective nodes directly below this common predecessor. When you have found the place of divergence, compare the attributes of the respective nodes from top to bottom and look for differences.

Note You can use »View«-»New window...« to open another QF-Test window and place the detail views of both nodes next to each other.

The only differences that will always lead to an error during recognition are changes to the attributes 'Class name' or 'Name'. Differences to 'Feature', structure or geomertry can usually be compensated for, provided they do not accumulate.

A change to the 'Class name' should seldomly happen when using Generic classes. Using generic classes offers a range of advantages, but in the case of web applications it is sometimes only introduced after creating first tests (see Improving component recognition with a CustomWebResolver). In this case you must adapt the 'Class name' attribute of the already created 'Component' nodes to this change.

The Component identifiers can change, too. If the change seems to be on purpose, for example correcting a grammatical error, you can adjust the 'Name' attribute accordingly. More probably it is an automatically generated Component identifiers which could change again at any time. Here it can make sense as well to discuss the issue with the developers and find a solution on the development side. Otherwise, for web applications the 'Name' can be influenced by installCustomWebResolver - Parameters via the parameters autoIdPatterns and customIdAttributes. In all technologies the 'Name' can be influenced using a NameResolver as described in subsection 50.1.6. It can be suppressed entirely or reduced to the relevant parts.

Changes to the attribute 'Feature' are not unusual, especially for 'Window' nodes. There, the 'Feature' corresponds to the title of the window. Combined with a significant change to geometry, this can cause the recognition to fail. This can be fixed by adjusting the 'Feature' attribute to the new circumstances, or - preferably - by using a regular expression (see section 45.3) which covers all variants.

Depending on the type and scope of the changes, there are two basic options for correction:

  • Adjust the attributes of the old node and remove the newly recorded nodes. If the changes to the SUT were small enough and the component recognition still works, changes can also be performed automatically via the QF-Test feature Update 'Components'.
  • Keep the new nodes and remove the old ones. For this you first must make sure that all nodes that refer to the old components are updated to the new 'QF-Test ID'. This can be achieved with a little trick: Change the 'QF-Test ID' of the old 'Component' node to the 'QF-Test ID' of the new one. QF-Test will initially complain that the 'QF-Test ID' is not unique, which you can ignore, and then will offer to update all references, which you need to confirm with "Yes". Then, you can remove the old node.

    Note The automatic adjustment of references in other test suite only works if they belong to the same project or if the attribute 'Dependencies (reverse includes)' of the 'Test-suite' node is set correctly.