This is a section you should hopefully never need to read. It
explains in detail how implicit 'Procedure' and 'Component'
references are resolved during test replay. If you need to read it,
your test suite include hierarchy probably is too complicated and
you should consider simplifying your includes.
There are basically two scenarios in which QF-Test must implicitly
resolve a 'Procedure' or 'Component' reference to another suite
when the requested 'Procedure' or 'Component' cannot be found in
the current (or explicitly referenced) suite:
-
The current suite includes other suites (by defining them in the
'Include files' attribute of the 'Test suite' root
node). In this case, QF-Test searches all included suites in the
given order.
-
The current suite (or rather one of its 'Procedures') was called
by another suite. Here QF-Test searches the calling suite for the
requested node.
The whole thing gets complicated, when (possibly indirect)
'Procedure calls' across test suite boundaries and (possibly
indirect, maybe even recursive) includes are combined.
Following are detailed explanations of the search algorithm that
will hopefully enable you to debug and resolve any include-file
related problems.
-
Whenever execution leaves the current suite to continue with some
'Procedure' or to retrieve a 'Component', the other suite
becomes the current suite. This process is complemented by two
things: the old suite is pushed onto the so-called
call-stack and the variable bindings of the new current
suite are pushed on top of the fallback bindings stack
(see chapter 6), so they override the
bindings of the old suite. In the run log this process is
documented by adding a Suite-change node which holds all
of the run log nodes for the execution that takes place outside
the old suite.
-
Any search through test suites starts with the current
suite, then continues top-down through the call-stack. So if, for
example, A calls B which calls C, then C is searched first,
followed by B and finally A.
-
Includes are considered stronger bindings than the call-stack.
This means that during the search through the current suite and
the suites on the call-stack, at each step the included
test suites are searched before moving to the next suite on the
call-stack. For example, if A calls B which includes C, A is on
the call-stack and B is the current Suite, then B will be searched
first, then C, and lastly A.
-
In case of multiple, possibly indirect includes, the search is
always conducted depth-first in the oder in which the include
files are listed. This means that if A includes B and C, and B
includes D, first A is searched, followed by B, then D and then C.
-
If a 'Procedure' is found (possibly indirectly) in an included
test suite (as opposed to the current suite, an explicitly
referenced suite or a suite on the call-stack), the change from
the old current suite to the new current suite doesn't take place
in one step. This has to be illustrated with an example right from
the start or we'll get totally lost: Let's say A calls B and that
A includes C. B calls a 'Procedure' which is found in C by way of
A. Instead of changing suites directly from B to C, A will first
become the current suite and then C. As a consequence, A gets
pushed onto the call-stack again on top of B and its variable
bindings are also pushed again on top of B's bindings on the
fallback bindings stack. The reasoning behind this is that C,
which is now the current suite, is "closer to" A, which includes
C, than it is to B, which only happened to be called by A. One
could also say that inclusion creates a kind of union, so that to
B, A and C will always appear as a single test suite as long as B
doesn't call C explicitly.
-
That's it, except for one thing: During a search QF-Test never
searches a suite twice. This would be useless in any case, but it
is more than an optimization, since it prevents trouble with
recursive includes if A includes B and B includes A.
If you really have a problem determining how, why or why not a
certain 'Procedure' or 'Component' was retrieved, first take a
look at the run log. It shows exactly which suites were used and
which variable expansions took place.