Sponsored Links
Swing Testing Tutorials
- Swing Extreme Testing
- Swing Extreme Testing - Outline of the Unit Test
- Swing Extreme Testing - Getting the Text of a Text Field
- Swing Extreme Testing - Unit Test Infrastructure
- Swing Extreme Testing - The ShowerThread Class
- Swing Extreme Testing - The init() Method
- Swing Extreme Testing - The Constructor Test
- Swing Extreme Testing - The wasCancelled() Test
- Swing Extreme Testing - The name() Test
- Swing Extreme Testing - The Data Validation Test
Tutorials
Swing TestingSwing Extreme Testing - The Data Validation Test
The Data Validation Test
The Ok button of the SaveAsDialog should only be enabled if the name that has been entered is valid. A name can be invalid if it contains an illegal character, or if it has already been used.
To test this behavior, we type in an invalid name, check that the Ok button is not enabled, then type in a valid name and test that it now is enabled:
- ui.enterName( "*" )
assert !UI.isEnabled( ui.okButton() ) ui.enterName( "remus") assert UI.isEnabled( ui.okButton() )
Our validateDataTest() started with a single block of code like that above. This block of code was copied and varied with different invalid strings:
- public boolean validateDataTest() { //First check names that have illegal characters. init()
ui.robot.type( " " ) assert !UI.isEnabled( ui.okButton() ) ui.enterName( "remus") assert UI.isEnabled( ui.okButton() ) ui.enterName( "*" ) assert !UI.isEnabled( ui.okButton() ) ui.enterName( "remus") assert UI.isEnabled( ui.okButton() ) ... //Seven more blocks just like these. ... cleanup() return true }
Later on, this was refactored to:
- public boolean validateDataTest() { init()
//First check names that have illegal characters. checkOkButton( " " ) checkOkButton( "*" ) checkOkButton( "/" ) checkOkButton( "\\" ) //Now names that are already there. checkOkButton( "albus" ) checkOkButton( "Albus" ) checkOkButton( "ALBUS" ) checkOkButton( "MINERVA" ) cleanup() return true } private void checkOkButton( String name ) { ui.enterName( name ) assert !UI.isEnabled( ui.okButton() ) ui.enterName( "remus" ) assert UI.isEnabled( ui.okButton() ) }
The refactored code is much more readable, contains fewer lines, and does not contain the useless repeated test for the illegal string "*" that the original does. This illustrates a good point about writing test code. Because a lot of tests involve testing the state of an object against various simple inputs, it is very easy for such code to end up being unreadable and horribly repetitive. We should always be looking to refactor such code. Not only will this make the tests easier to maintain, it also makes the code more interesting to write. As we argued in Chapter 1, we should apply the same quality standards to our test code that we do to our production code.
The Usability Test
Typically, a simple dialog should be able to be cancelled with the Escape key, and the Enter key should activate the Ok button. In this test, we check these usability requirements and also check that tabbing to the buttons and activating them with the space key works as expected.
- public boolean usabilityTest() { //Check that 'escape' cancels. init()
ui.robot.escape() assert !UI.isShowing( ui.dialog() ) assert wasCancelled() cleanup() //Check activating the cancel button when it has focus. init() ui.robot.tab() //Only one tab needed as ok is not enabled. ui.robot.activateFocussedButton() assert !UI.isShowing( ui.dialog() ) assert wasCancelled() cleanup() //Check that 'enter' is like 'ok'. init() ui.robot.type( "remus" ) ui.robot.enter() assert !UI.isShowing( ui.dialog() ) assert !wasCancelled() assert enteredName().equals( new IkonName( "remus" ) ) cleanup() //Check activating the ok button when it has focus. init() ui.robot.type( "remus" ) ui.robot.tab() ui.robot.activateFocussedButton() assert !UI.isShowing( ui.dialog() ) assert !wasCancelled() assert enteredName().equals( new IkonName( "remus" ) ) cleanup() return true }
Summary
This chapter and the two preceding ones have given us all the principles we need to write solid, automated, and fairly painless tests for our user interfaces. The key points are:
• We should write a UI Wrapper class for the class we are testing and use it to manipulate the test objects.
• All creation and setup of components must be done in the event thread.
• All querying of the state of components must be done in a thread-safe manner.
• Any variable, either in a user interface or in a handler, that is set from the event thread needs to be read in a thread-safe manner.
The class UI contains a lot of methods for making it easy to follow these principles. In the next chapter we'll see more of this useful class.
Comments
Sponsored Links
