11.5 Testing Swing GUIs

11.5.1 Problem

You want to use a specialized toolkit for testing Swing GUI code.

11.5.2 Solution

Try out Abbot, Pounder, Jemmy, or JFCUnit.

11.5.3 Discussion

Testing GUI code is challenging. You locate GUI components, simulate user input, and capture the actual output to test against your expected output. You must also deal with threading issues, because many Swing events are delivered asynchronously on the event queue.

Minimizing dependency on GUI tests is always your first line of defense. You should make every effort to modularize your GUI code so that data models can be tested independently from the GUI. You can also write many tests against individual panels and components. But at some point, you may find that you have to run tests against the entire user interface in order to fully simulate how the user works with your application. This is where specialized GUI testing tool enter the picture.

11.5.3.1 Abbot

Abbot is a testing framework that builds on functionality offered by the java.awt.Robot class. In Abbot, you create testing scripts that locate components, perform actions, and then assert that the GUI is in the correct state. These scripts are your automated GUI tests. Although you can use the Abbot API to write tests programmatically, Abbot scripts are normally used for testing.

You generally create a script by running your application while Abbot Recorders capture all events and generate the script for you. Then use the Costello script editor to change and customize your scripts. Next, insert assertions and tests into your scripts. Then run Abbot scripts through JUnit using the ScriptTestCase and ScriptTestSuite classes, or you can run them interactively using the Costello script editor.

11.5.3.2 Pounder

Pounder is another recording/playback tool, much along the same lines as Abbot. You record scripts by running your application in the Pounder tool, and then play them back using the Player class. After the script completes, you can use normal Java code, rather than assertions in the scripts, to assert that the various GUI components are in the expected state. For example:

public void testLoginFrame(  ) throws Exception {
    Player player = new Player("scripts/login/badUserName.pnd");
    LoginFrame loginFrame = (LoginFrame) player.play(  );

    assertEquals("joe", loginFrame.getUserNameField().getText(  ));
    etc...
}
11.5.3.3 Jemmy

Jemmy is a NetBeans module for testing GUI components, but is also designed for use as a standalone class library. Unlike Abbot and Pounder, Jemmy is not a recording and playback tool. Instead, Jemmy includes a comprehensive Java API for dealing with Swing user interfaces.

One advantage of a tool like Jemmy is its ability to locate components based on their content, rather than requiring the exposure of the accessor methods in the panels and frames being tested. Without Jemmy's searching capabilities, you would either have to write your own searching methods, or else write a lot of methods in your GUI code like getFirstNameField( ) that would allow your unit test to locate fields and run tests against them.

11.5.3.4 JFCUnit

JFCUnit is similar in concept to Jemmy; it is another Java class library for writing Swing unit tests. Like Jemmy, JFCUnit allows you to programmatically locate windows and components within those windows, deliver events, and then test component states in a thread-safe way.

11.5.4 See Also

Abbot is available at http://abbot.sourceforge.net. Pounder is available at http://pounder.sourceforge.net. Jemmy is available at http://jemmy.netbeans.org. JFCUnit is available at http://jfcunit.sourceforge.net.