This version 0.12.3 (040611)
package example;
import junit.extensions.abbot.*;
import abbot.tester.*;
public class ArrowButtonTest extends ComponentTestFixture {
public ArrowButtonTest(String name) { super(name); }
public static void main(String[] args) {
TestHelper.runTests(args, ArrowButtonTest.class);
}
}
We'll need to put the component into a frame for most tests, but there's already a "showFrame" method in the ComponentTestFixture that we inherit. That method puts a nice fat border around our component to make it visible, although that's not strictly necessary. We'll need a ComponentTester to play actions on our component, so add that to the setup:
private ComponentTester tester;
protected void setUp() {
tester = new ComponentTester();
}
Now write the first test, which ensures that an action is fired when the button is clicked.
import java.awt.event.*;
import javax.swing.*;
...
private String clickType;
public void testClick() {
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ev) {
clickType = ev.getActionCommand();
}
};
ArrowButton left = new ArrowButton(ArrowButton.LEFT);
ArrowButton right = new ArrowButton(ArrowButton.RIGHT);
ArrowButton up = new ArrowButton(ArrowButton.UP);
ArrowButton down = new ArrowButton(ArrowButton.DOWN);
left.addActionListener(al);
right.addActionListener(al);
up.addActionListener(al);
down.addActionListener(al);
JPanel pane = new JPanel();
pane.add(left);
pane.add(right);
pane.add(up);
pane.add(down);
// ComponentTestFixture provides the frame
showFrame(pane);
clickType = null;
tester.actionClick(left);
assertEquals("Action failed (left)", ArrowButton.LEFT, clickType);
clickType = null;
tester.actionClick(right);
assertEquals("Action failed (right)", ArrowButton.RIGHT, clickType);
clickType = null;
tester.actionClick(up);
assertEquals("Action failed (up)", ArrowButton.UP, clickType);
clickType = null;
tester.actionClick(down);
assertEquals("Action failed (down)", ArrowButton.DOWN, clickType);
}
If we were writing the ArrowButton from scratch, we'd have identified by this
test a few things that we need:
java -Dabbot.robot.auto_delay=200 -cp classes example.ArrowButtonTest
Note that the auto-delay setting is only there to prevent the test from
running so fast you don't see it; normally you can omit it.
That leaves only the last bullet to test, repeated events when held down.
private int count = 0;
public void testRepeatedFire() {
ArrowButton arrow = new ArrowButton(ArrowButton.LEFT);
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ev) {
++count;
}
};
arrow.addActionListener(al);
showFrame(arrow);
Dimension size = arrow.getSize();
// Hold the button down for 5 seconds
tester.mousePress(arrow);
tester.actionDelay(5000);
tester.mouseRelease();
assertTrue("Didn't get any repeated events", count > 1);
}
Run the test case again, and (if you were writing ArrowButton from scratch)
the second test would fail. Go back and implement the repeated fire function
in example.ArrowButton, and debug and test until testRepeatedFire passes.
Now you've increased your confidence that subsequent changes to ArrowButton
which break the desired behavior will break the tests and you'll know about
it. You've also just documented the expected behavior, which can mean the
difference between someone understanding your code or someone using it
incorrectly based on out-of-date or missing documentation.