|
Testing GUIs with TextTest and xUseCase
Allowing recording and replaying of waits
A typical GUI application has the requirement of instant
response to its user at all times. It cannot just lock up while
some background processing (e.g. loading in a large amount of
data) is done. This means that a large number of GUIs have
multiple threads, and any acceptance testing approach for GUIs
must therefore consider how to handle this problem.
When we replay a test without human intervention, it may well
be necessary to wait for things to happen before proceeding.
Otherwise the test will fail because further use case actions
rely on data loaded in a separate thread being present. In this
case a traditional record/replay tool is basically stuck: it
knows nothing of application intent and all it can do is ask the
test writer to hand-insert 'sleep' statements into the script
after recording it. Needless to say, this is both inefficient
and error-prone: it can easily be forgotten, and the required
length of sleep is hard to get right.
Use-case recorders handle this situation by introducing the
notion of an `application event': the application can simply
notify the use-case recorder when a significant event has
occurred that is worth waiting for. At places in the code where
such events occur, the programmer adds calls to xUseCase, which
will then record a `wait
for <name of application event>' command to the usecase it is recording.
During replay it will simply not replay any further events until the application
reaches the same point, i.e. when the same call is made. A single simple call
can therefore be used for both purposes.
So, xUseCase recording with application events looks like
this:
 Replaying,
with application events, looks like this:
Now for an example. Assume we have the following use case
script:
load movie data into list
select movie Die Hard
Also assume that the first command starts a separate thread that
loads a large amount of data from a database and displays it on
the screen. Unless there is a way of telling the replayer when
this has completed, it would perhaps try to select `Die Hard'
before that item was present in the list, causing the simulation
to fail. To solve this, the programmer finds the point in his application
directly after the loading is completed and inserts the following code :
import usecase
usecase.applicationEvent('data to be loaded')
if he writing a Python GUI and using PyUseCase or
ScriptEngine.instance().applicationEvent('data to be loaded');
if he is writing a Java GUI and using JUseCase. Either way, the recorded use case will now look like this:
load movie data into list
wait for data to be loaded
select movie Die Hard
In record mode the applicationEvent method just records the
'wait for' command to the script file when it is called, as
shown here:
 In
replay mode, the simulator (or replayer) halts replaying on
reading this 'wait for' command, and the applicationEvent call
then acts as a notifier to tell it to resume when the data has
been loaded.
|