UISpec4J - NetBeans Example
UISpec4J is an Open
Source
functional and/or unit testing library for Swing-based Java
applications, built on top of JUnit.
Prerequisites
JDK 1.7
Download the Accumulator project Zip file:
Accumulator.zip
Unzip the file.
If you don't want to use the NetBeans IDE, you can run the
corresponding Ant targets from the command line.
Accumulator application
Run the
application
- Start NetBeans 7.3.1.
- From the menubar select File > Open Project and
navigate to
the Accumulator project folder.
- Run the project.
- Type "7" in the text field and click the "+" button. The
Total
field will change to 7.
- Type "3" in the text field and click the "-" button. The
Total
field will change to 4.
- From the Help menu select About. A popup dialog
shows where
an About message will appear. Click "OK". Close the
application.
SwingView class
- Open the SwingView class in the editor.
- SwingView has a constructor, three actionPerformed
methods, and a
refresh() method.
- Observe in the constructor that each Swing component has
been
given a name using the setName() method. This is necessary
so that
UISpec4J can locate the component at runtime.
txtEntry.setName("Entry"); btnPlus.setName("Plus"); btnMinus.setName("Minus"); txtResult.setName("Result"
|
UISpec4J Test classes
The application contains four sample unit tests that demonstrate
different features of UISpec4J.
SimpleTest
The simplest kind of GUI test you can write.
It creates an instance of a JFrame (line 3)
Locates the text entry field using the string we assigned the
component
with setName().(line 6)
Places some text into it (line 7)
Locates the plus button (line 8) and clicks it (line 9)
Then makes an assertion about the content of the results field
(line
12).
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
public void testAdd() { SwingView view = new SwingView(); /* Note: Window, TextBox, and Button are UISpec4J classes */ Window win = new Window(view); TextBox entry = win.getInputTextBox("Entry"); entry.appendText("5"); Button plus = win.getButton("Plus"); plus.click(); TextBox result = win.getTextBox("Result"); /* Standard JUnit assert */ assertEquals("5", result.getText()); }
|
Three things to note about this simplest kind of test case.
* It extends JUnit TestCase, not UISpecTestCase.
* Therefore, it uses standard JUnit-style asserts,
not the
UISpec-style.
* It instantiates just a single GUI frame; it doesn't run
the
application main method.
NormalTest
This test extends UISpecTestCase. As a result, it
can use
some special forms of assert that can directly interrogate the
UISpec4J
components.
Line 6 asserts that the window title bar is displaying a
particular
string.
Line 13 asserts the result field text is displaying a particular
string.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
public void testAdd() { SwingView view = new SwingView(); /* Note: Window, TextBox, and Button are UISpec4J classes */ Window win = new Window(view); assertTrue(win.titleEquals("Calc")); TextBox entry = win.getInputTextBox("Entry"); entry.appendText("5"); Button plus = win.getButton("Plus"); plus.click(); TextBox result = win.getTextBox("Result"); // UISpec-style assert assertTrue(result.textEquals("5")); }
|
Three things to note
* It extends UISpecTestCase, not JUnit TestCase
* It uses special UISpec-style asserts.
* It instantiates just a single GUI frame; it doesn't run
the
application main method.
AppTest
In a more complex application you might want to test the entire
GUI by
running the application's main method, not just a single
JFrame.
To do that, call the setAdapter() method inside setUp() (Line
3). Then
in line 8 call getMainWindow().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
protected void setUp() throws Exception { setAdapter(new MainClassAdapter(Main.class, new String[0])); }
public void testAdd() { Window mainWindow = getMainWindow(); /* Note: Window, TextBox, and Button are UISpec4J classes */ assertTrue(mainWindow.titleEquals("Calc")); TextBox entry = mainWindow.getInputTextBox("Entry"); entry.appendText("5"); Button plus = mainWindow.getButton("Plus"); plus.click(); TextBox result = mainWindow.getTextBox("Result"); // UISpec-style assert assertTrue(result.textEquals("5")); }
|
Three things to note
* It extends UISpecTestCase, not JUnit TestCase
* It uses special UISpec-style asserts.
* It instantiates the application main method.
PopupTest
This test demonstrates the ability to intercept a dialog that
pops up
at run time, interrogate its fields, and then close it.
Refer to
the UISpec4J documentation for the details of this technique.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
/* This is needed for the next test, otherwise the dialog is displayed instead of being intercepted by UISpec */ static { UISpec4J.init(); }
public void testAbout() { SwingView view = new SwingView(); Window win = new Window(view); // Select About from the Help menu and // Check that the About box displays properly WindowInterceptor.init(win.getMenuBar().getMenu("Help").getSubMenu( "About").triggerClick()). process(BasicHandler.init(). assertContainsText("About"). triggerButtonClick("OK")).run(); }
|
Execute the tests
- Right-click on the project node and select "Test"
(Alt-F6).
- The four tests should all pass. (You may get a
warning "Cannot
convert string ... to type
FontStruct" that can be ignored.
- Note that the tests don't run quite as fast as a typical
JUnit
test, because there's a lot of reflection and graphics stuff
going on
in the background that slows it down. But it is much
faster than
a "record-playback" style test (E.g., Costello).
Troubleshooting
If running the test produces this error:
java.lang.UnsatisfiedLinkError: sun.awt.motif.MToolkit.init(Ljava/lang/String;)V
you probably aren't using JDK1.7 as specified in the Prerequisites.
On some machines running the test may result in an error:
Can’t load library:
/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/motif21/libmawt.so
In the CSL labs on CentOS, this is because a Motif library is
in the wrong location.
One workaround is to use Sun's JDK instead of Open JDK.
Start NetBeans from the command line and point it to the Sun JDK
installed in the instructor's grader
account.
/usr/local/netbeans-6.9.1/bin/netbeans --jdkhome /home/graderjd/jdk1.6.0_30
A second workaround is simpler but may not work in all
situations.
Open a terminal window and type this line:
export AWT_TOOLKIT=XToolkit
Then you can type "ant test" to run the tests at the command
line, or you can start the NetBeans IDE with the appropriate
command.