Overview

UISpec4J provides three different sets of components:

There are two main usages for UISpec4J: writing unit tests for individual panels and dialogs, or writing functional/acceptance tests for the whole application.

Prerequisites

In this documentation, we suppose that you already have some experience with JUnit. If that is not the case, we invite you to learn more about JUnit on its website: http://www.junit.org.

To use UISpec4J, you will need a Java Development Kit version 1.4.2 or later.

Installation

UISpec4J runs in the same JVM as your application (or at least the client application if you are testing a distributed system). In order to run the tests, you will need to add uispec4j-xxx.jar to your classpath, along with its dependencies. You can download or find these JARs from our downloads page.

Initializing UISpec4J

In order for UISpec4J to be fully operational, you will need to call the UISpec4J.init() method before doing anything with Swing (please refer to the interception documentation for further details).

For your first test case, you can just call that method from the static initializer of your test class:

public class MyOwnTest extends TestCase {
  static {
      UISpec4J.init();
  }

  public void testSomething() {
    ...perform your tests here...
  }
  ...

Please note that having UISpec4J run on Linux may require some adjustements - please refer to our troubleshouting page for further details.

Writing unit tests

In most cases, you will have classes that represent panels in the user interface. These classes will typically extend or create a JPanel containing the Swing components to be displayed:

public class MyOwnPanel extends JPanel {
  ... provide your own panel contents and behaviour ...
}

All you need to do for unit-testing such a class is to stick the JPanel into an UISpec4J Panel wrapper, and then start retrieving and using individual components:

public class MyOwnPanelTest extends TestCase {
  public void testInitialState() {
    ... setup the context needed to instanciate MyOwnPanel ...
    Panel panel = new Panel(new MyOwnPanel(...));
    panel.getTable().contentEquals(...);
    ...
    panel.getButton("Apply").click();
    ...
    }
  }
...

Writing functional tests

In the case of functional tests, we do not want to test individual GUI classes, we want to access the application as a whole. To support this, we propose a specific TestCase class - UISpecTestCase - which offers the following interface:

public void UISpecTestCase extends TestCase {
  public Window getMainWindow();
}
        

To write a functional test case, you simply need to subclass UISpecTestCase an start using the Window component returned by getMainWindow() to retrieve its individual GUI components:

public void MyFunctionalTestCase extends UISpecTestCase {
  public void test() {
    Window mainWindow = getMainWindow();
    mainWindow.getMenuBar().getMenu("File").getSubMenu("Open...").click();
    ...
    mainWindow.getTree().contentEquals(...);
  }
}

In an Extreme Programming setting, these tests are written before the corresponding features are made available in the application, and they are written by testers instead of developers.

To support this, the UISpecTestCase has been designed so that the tests can be implemented and compiled without depending on the application. The binding with the application is established at runtime, through the UISpecAdapter interface:

public interface UISpecAdapter {
  Window getMainWindow();
}

This interface is meant to be implemented by developers, who will certainly initialize their application and return a Window component wrapping the JFrame instance corresponding to the application's main window.
The UISpecAdapter is then plugged into the tests suite by setting the uispec4j.adapter property:

java -cp ... -Duispec4j.adapter=com.mycomp.MyUISpecAdapter ...

The tool will then use Java's reflection mechanism to instanciate the adapter and initialize the UISpecTestCase in its setUp() method.

Another way to set up the adapter is to call the UISpecTestCase.setAdapter() method from within your test class, for instance in its setUp() method.