Navigation: home >ui testing>appevents
Testing GUIs with TextTest and StoryText
Multi-threaded simulation using Application Events
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. Many applications therefore do significant work in the background.
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. Sometimes the control we want to use is not available until the background processing is complete - in this case we can simply wait until it is, but this is not always the case.
In this situation a traditional recording tool can do one of three things:
  1. It can insert a sleep based on how long the user waited
  2. It can record waits for everything that ever changes in the GUI
  3. It can rely on the user fixing up the recorded script somehow after the fact.
None of which are very good, because
  1. With sleeps, you typically need 10 times the time you expect for reliability. This means you either get very slow tests or very unreliable ones.
  2. If you wait for everything that ever changes, 99% of it is irrelevant and clogs up the script with stuff that is waiting to break.
  3. This requires that the user both know it is necessary and know what to do, and have the skills to do this in a reliable way.
StoryText handles this situation by involving the development team and instrumenting the code. By relatively simple instrumentation we can fix the synchronisation for all tests past, present and future, and we can make the waiting robust by talking in semantic terms instead of for example waiting for progress bars to appear and then disappear.
We therefore introduce the notion of an `application event': the application can simply notify StoryText 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 StoryText (in Python code) or generates an event (in Java code), 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, StoryText 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' as soon as that item was present in the list, and the subsequent test may assume that all the data was present to get the right answer. To solve this, the programmer finds the point in his application directly after the loading is completed and inserts the following code :
import storytext
storytext.applicationEvent('data to be loaded')
if they are writing a Python GUI or
import org.eclipse.swt.widgets.Event;

Event event = new Event();
event.text = "data to be loaded";
someWidget.notifyListeners(1234, event);
if they are writing an SWT/Eclipse RCP GUI in Java. (There is a third form for Swing GUIs) 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.

To see how this works in practice, look at the relevant StoryText documentation.

Last updated: 05 October 2012