50.1 Advanced script concepts
50.1.1 Module load-path
The load-path for scripting modules is assembled from various sources in the following order:
- the script directory in the user configuration directory
-
the directory
qftest/qftest-10.0.0/<scriptlanguage>
In addition, during Server script or SUT script node execution, the directory of the containing test suite is prepended to the path.
The directory
qftest/qftest-10.0.0/<scriptlanguage> contains
internal modules of the specific script language. You should
not modify these files, since they may change in later versions of
QF-Test.
The script directory in the user configuration directory is the place to put your own shared modules. These will be left untouched during an update of QF-Test. You can locate the rescpective script directory via »Help« under "System info" as "dir.<scriptlanguage>".
Modules that are specific to a test suite can also be placed
in the same directory as the test suite. The file extension for all
modules must be .py.
In Jython you can add additional directories to the load-path by defining the python.path
system property.
50.1.2 The plugin directory
The script languages can also be used to access Java classes and methods beyond the scope of QF-Test by simply importing such classes, e.g.
from java.util import Date
from java.text import SimpleDateFormat
print SimpleDateFormat("yyyy-MM-dd").format(Date())
The classes available for import are those in the Java class path, i.e. all classes
of the standard Java API and QF-Test's own classes. Note that QF-Test ignores the CLASSPATH
environment variable, but you may define QFTEST_CLASSPATH with the same value if necessary
(e.g. to start a client application). For the SUT things also depend on the ClassLoader concept in use.
WebStart and Eclipse/RCP in particular make it difficult to import classes directly from
the SUT.
Additionally, there are plugin directories into which you can simply drop a jar file to
make it available to scripts.
QF-Test searches for a directory called plugin.
You can locate the currently used plugin directory via »Help« under "System info" as "dir.plugin".
The location of the plugin directory can be overridden with the command line argument
-plugindir <directory>.
Jar files in the main plugin directory are available to both
Server script and SUT script nodes. To make a jar
available solely to Server scripts or solely to
SUT scripts, drop it in the respective subdirectory called
qftest or sut instead.
Note For a practical introduction to QF-Test plugins, check out our blog post Introduction to QF-Test Plugin Development.
50.1.3 Initialization (Jython)
During QF-Test and SUT startup an embedded Jython interpreter is
created. For QF-Test, the module named qftest is
imported, for the SUT the module named qfclient.
Both are based on qfcommon which contains shared code.
These modules are required to provide the run context interface and
to set up the global namespace.
Next the load-path sys.path is searched for your
personal initialization files. For QF-Test initialization, the file
called qfserver.py is loaded, the file called
qfsut.py is used for the SUT. In both cases
execfile is used to execute the contents of these files
directly in the global namespace instead of loading them as
modules. This is much more convenient for an initialization file
because everything defined and all modules imported will be directly
available to Server scripts and SUT scripts. Note that
at initialization time no run context is available and no
test suite-specific directory is added to sys.path.
50.1.4 Namespace environment for script execution (Jython)
The environments in which Server scripts or SUT scripts are executed are defined by the global and local namespaces in effect during execution. Namespaces in Jython are dictionaries which serve as containers for global and local variable bindings.
The global namespace is shared between all scripts run in the same
Jython interpreter. Initially it will contain the classes
TestException and UserException, the
module qftest or qfclient for QF-Test or
the SUT respectively, and everything defined in or imported by
qfserver.py or qfsut.py. When assigning a
value to a variable declared to be global with the
global statement, that variable is added to the global
namespace and available to scripts run consecutively. Additionally,
QF-Test ensures that all modules imported during script execution are
globally available.
The local namespace is unique for each script and its lifetime is
limited to the script's execution. Upon invocation the local
namespace contains rc, the interface to QF-Test's
run context, and true and false bound to
1 and 0 respectively for better
integration with QF-Test.
Accessing or setting global variables in a different Jython
interpreter is enabled through the methods fromServer,
fromSUT, toServer and toSUT.
50.1.5 Exception handling
All QF-Test Exceptions are
automatically imported inscripts and can be used for
try/except clauses like
try:
com = rc.getComponent("someId")
except ComponentNotFoundException:
...
ComponentNotFoundException in Jython
When working with Groovy you use try/catch:
try {
com = rc.getComponent("someId")
} catch (ComponentNotFoundException) {
...
}
ComponentNotFoundException in Groovy
Only the following exceptions should be raised explicitly from
script code (with raise or throw new respectively):
-
UserException("Some message here...")should be used to signal exceptional error conditions. -
BreakException()orraise BreakException("loopId")can be used to break out of a Loop or While node, either without parameters to break out of the innermost loop or with the QF-Test loop ID parameter to break out of a specific loop with the respective QF-Test ID. -
ReturnException()orraise ReturnException("value")can be used to return - with or without a value - from a Procedure node, similar to executing a Return node. To improve readability, preferably callrc.returnValue(...).
50.1.6 Debugging scripts (Jython)
When working with Jython modules you don't have to restart QF-Test
or the SUT after you made changes.
You can simply use reload(<modulename>) to load the module anew.
Debugging scripts in an embedded Jython interpreter can be tedious. To simplify this task, QF-Test offers an active console window for communicating with each interpreter. For more information please see the last part of "General".
Alternatively, a network connection can be established to talk remotely to the Jython
interpreter - in QF-Test as well as within the SUT - and get an interactive command line.
To enable this feature you must use the command line argument -jythonport <number> to set
the port number that the Jython interpreter should listen on. For the SUT
-jythonport=<port> can be defined in the "Extra"
Executable parameters of the Start Java SUT client or
Start SUT client node. You can then connect to the Jython interpreter, for
example with
telnet localhost <port>
Combined with Jython's ability to access the full Java API, this is not only useful for debugging scripts but can also be used to debug the SUT itself.