Monday, 4 January 2010

JUseCase, dreams of resurrection

JUseCase is the Java version of PyUseCase, for testing GUIs written in Swing. It was originally written as a master's thesis by Claes Verdoes in 2005, under Geoff's supervision. Since then it hasn't been used much, and has lain idle and unmaintained for a while. In the meantime, Geoff has made some major changes to PyUseCase, culminating in the recent release of version 3.0, which I think is hugely better than any competing tools. But then I am biassed :-)

I would love to see JUseCase resurrected and to support more of the features of PyUseCase 3.0. We originally got a lot of criticism of JUseCase that it required too many changes in application code; many developers are leery of changing their code to put in hooks "just for the tests". PyUseCase 3.0 removes the need for much of that, and I think JUseCase could do the same.

In JUseCase, you have to connect widgets to domain actions by adding bits of code like this:

JTextField originField = new JTextField(“ANY");
ScriptedTextField.connect("choose origin", originField, ScriptedTextField.EDIT);

i.e. the text field "originField" should record a domain action "choose origin" when it is edited. This enables JUseCase to record and replay user actions in a domain language, at a higher level of abstraction than just widget names.

In PyUseCase 3.0 these kinds of code changes are replaced by the UI map file. Widgets are identified by name, something like this:

[Name=originField]
edited = choose origin

So all you have to do in the code is make sure all your widgets have unique names. Good names are useful for accessability, (blind people etc), and for internationalization, so you can argue you're not just doing it for the tests.

The second thing that PyUseCase 3.0 does to reduce code changes is to automatically generate the UI log, rather than you having to insert log statements by hand. The UI log is the part of the test definition that TextTest uses to assert the application is behaving correctly. It should be a low-fidelity rendering of what the UI looks like, in plain text.

For example, for the simple application in my last post, the ui log might look like this:

---------- Window 'Book Animals for Procedures' ----------
Focus widget is 'available procedures'
Showing available procedures with columns: available procedures
-> abdominocentesis
-> haircut
-> re-shoe
-> milking ,
Showing available animals with columns: available animals , animal type
-> Good Morning Sunshine | mare
-> Goat 3 | goat
-> Goat 4 | goat
-> Guicho | gelding
-> Misty | mare
Button 'book'


This log is created just by inspecting the GUI elements in turn, and writing out a sketch of their contents.

In order to add to this log as the user interacts with the application, PyUseCase attaches itself as a listener to each widget, so it finds out when they change. Then after the user has done some actions, when the GUI event queue is empty, it takes the opportunity to write a few log statements about what has changed since the last time it logged something. In this way it produces a neat summary of what the user does and what the UI looks like after each action. I should think JUseCase could do something similar.

Then all that is left to hand code is to put in the application events - basically writing a log statement that you're doing something in another thread of execution, that the tests should wait for before proceeding. There shouldn't be too many of those calls, so hopefully they can slip under the radar.

Anyone looking for a masters thesis topic fancy giving it a go?

No comments:

Post a Comment