Abbot framework for testing Java GUI components and programs
All materials Copyright © 2002 All Rights Reserved Timothy Wall

This version 0.9.0 (030527)

Tutorial 2: Testing A Group of Components (Part I)

This is a short example of how to write tests against a composite component prior to writing it. This example is written in the context of JUnit, and assume you're familiar with that framework. If not, read the cookbook first.

How to write a simple test fixture

In this example, we want to write a component which displays the currently selected item from list in a label below that list. We first write a test fixture that displays our LabeledList (the main routine automatically runs the test suite for this fixture, or runs a single test if one is specified on the command line). Explicitly disposing of the frame is not necessary, since the ComponentTestFixture will dispose of any frames after tests finish running, but it's a good habit to dispose of frames when you don't need them any longer.


import java.awt.*;
import javax.swing.*;
import junit.framework.*;
import junit.extensions.abbot.*;

import abbot.script.ComponentReference;
import abbot.tester.ComponentTester;

public class LabeledListTest extends ComponentTestFixture {

    public void testLabelChangedOnSelectionChange() throws Throwable {
        String[] contents = { "one", "two", "three" };
        LabeledList labeledList = new LabeledList(contents);
        Frame frame = showFrame(labeledList);
        // ...
    }

    public LabeledListTest(String name) { super(name); }

    public static void main(String[] args) {
        TestHelper.runTests(args, LabeledListTest.class);
    }
}
This won't compile until we get a LabeledList to test against, so let's do that.

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class LabeledList extends JPanel {
    private JList list;
    private JLabel label;
    public LabeledList(String[] initialContents) {
        setLayout(new BorderLayout());
        list = new JList(initialContents);
        add(list, BorderLayout.CENTER);
        label = new JLabel("Selected: ");
        add(label, BorderLayout.SOUTH);
    }
}
Now we go back and add to the test. We want to select a list item and ensure that the label reflects the selected item. So we first look up the list. Note that while we could make the LabeledList member public or otherwise directly accessible, that's making private data visible solely for the sake of a test, and ends up cluttering the interface. Let the Abbot framework do the work instead...

    public void testLabelChangeOnSelectionChange() throws Throwable {
        // ...

        ComponentReference ref = new ComponentReference("list", JList.class);
        Component list = getFinder().findComponent(ref);
In order to play actions on the list, we want a ComponentTester object that knows how, so we can create a JListTester (or let the ComponentTester do it and cache the result for future tests).

       JListTester tester = (JListTester)ComponentTester.getTester(list);
       tester.actionSelectIndex(list, 1); 
       // tester.actionSelectValue(list, "two"); // or select by value
At this point the selection has finished and any listening events propagated, so you can check the results:

       ref = new ComponentReference("label", JLabel.class);
       JLabel label = (JLabel)getFinder().findComponent(ref);
       assertEquals("Wrong label after selection",
                    "Selected: two", label.getText());
    }
Now run the test. It will fail, because we haven't implemented anything in the LabeledList to update the label when a selection is made. We do so now.

    public LabeledList(String[] initialContents) {
        // ...
        list.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent lse) {
                label.setText("Selected: " + list.getSelectedValue());
            }           
        });
    }
Recompile and the test should now pass.

This project runs on
SourceForge Logo