If you don't already know, there is roughly three types of testing you can do to attest the quality of your software: unit testing (testing a single module or class), functional testing (or integration testing; validating the overall functionality of the whole software against the specifications) and performance testing (speed, memory, scalability...).
Now if you want to test a GUI in Java implemented with Swing, how do you do it? Well, for performance, you'll have to improvise by asking "potential users" to use the GUI for a couple of hours, and see if they think the GUI is "easy to use" or "responsive", etc.
But for functional testing, you should have a clear set of requirements in the specs, for example "if you click button 'Add', then the sum of fields 'A' and 'B' should be placed in field 'Sum'. Even more complex, you have scenarios like "if you press enter in either field 'A' or 'B', then it is as if you clicked on button 'Sum'". So you have a GUI that looks like this:
The code for when you click on "Add" and when you press enter are pretty simple:
private void bFieldActionPerformed(java.awt.event.ActionEvent evt) { addButton.doClick(); } private void aFieldActionPerformed(java.awt.event.ActionEvent evt) { addButton.doClick(); } private void addButtonActionPerformed(java.awt.event.ActionEvent evt) { double aVal, bVal; try { aVal = Double.parseDouble(aField.getText()); } catch (NumberFormatException ex) { sumResultLabel.setText("Field A is not a number"); return; } try { bVal = Double.parseDouble(bField.getText()); } catch (NumberFormatException ex) { sumResultLabel.setText("Field B is not a number"); return; } sumResultLabel.setText(Double.toString(aVal + bVal)); }
That was pretty simple, but when you want to do functional testing, are you going to manually use the GUI for every test? Well, not if you're using UISpec4J. Automated testing, done with JUnit, would be done like this for the above two specifications:
public void testCorrectSum() { Panel panel = new Panel(new MyWindow()); panel.getInputTextBox("aField").insertText("2.5", 0); panel.getInputTextBox("bField").insertText("3.5", 0); panel.getButton("Add").click(); assertEquals(6.0, Double.parseDouble(panel.getTextBox("sumResult").getText()), 0.0); } public void testEnterKey() { Panel panel = new Panel(new MyWindow()); panel.getInputTextBox("aField").insertText("2.5", 0); panel.getInputTextBox("bField").setText("3.5"); //this does the "press enter" assertEquals(6.0, Double.parseDouble(panel.getTextBox("sumResult").getText()), 0.0); }
Wow, that was simple. Combine this with FitNesse, a wiki-based functional testing environment (see this for a quick example), and you now have a great way to automate all functional testing and changes in the specifications (and the GUI).
Before you jump on those libraries, here are some caveats you have to be aware of:
Published on October 9, 2005 at 15:58 EDT
Older post: Java Coding Style Tools
Newer post: When ego destroys open source