JUnit
•	References
•	Principles
•	Design
•	Basics
•	Fixtures
•	Test Suites
References
•	http://www.junit.org 
•	Documentation accompanies download
Principles
•	Test writing as part of development
–	To show the program works
–	More reliable than saying it works
•	Long-term value of tests
–	What is important here?
–	ex: need to be able to combine tests
Principles
•	Test writing must be convenient
–	or else it won't get done
–	should not need new concepts
–	test cases implemented as objects
Design
•	TestCase class defined
–	abstract class
–	developer defines subclass
–	methods: setUp(), runTest(), tearDown()
–	setUp() for initialization, tearDown() for cleanup
–	developer overrides
–	run() calls these in order
Results
•	Failures vs. errors
–	Failure: "expected" error
–	implies test ran but gave wrong result
–	Error: unexpected error
•	What if test case code fails?
–	How would you do this in the test case class?
–	How is this undesirable?
Results (cont'd.)
•	Solution: use Exceptions
–	How do exceptions help?
•	TestResult class
–	pass as param to run()
–	startTest(TestCase) to start
–	startTest() may run in threaded envt. -- synchronized
Basics
•	Add directory with junit.jar in CLASSPATH variable
–	[CLASSPATH is a string of directories searched for compiled class files, "jar" is Java archive format]
•	Define subclass of TestCase class
•	Check result using assertTrue(<cond>);
–	<cond> is true if code passes test
Basics
•	Override runtest() method
•	OR let JUnit take care of it for you by creating a suite
Fixtures
•	Repeating initialization and cleanup code is tedious and error-prone
•	Put common code in setUp() and tearDown()
Test Suites
•	Repeating tests is tedious
•	What would be bad about having one class for each test?
•	A test suite is a collection of related tests
–	TestSuite class collects tests
–	Still want to run the tests, so TestSuite and TestCase support same interface
Test Suites (cont’d)
•	Problem: sets of tests often change
–	Each new test or dropped test requires modifying the code that calls each test
•	JUnit solution: automatically extract tests
–	Constraints:
•	Each test has separate method
•	Method must be named “testSomething()”
•	Method must be public, void, and without parameters
Example (from JUnit FAQ)

import java.util.*;
import junit.framework.*;

public class SimpleTest extends TestCase {

    public SimpleTest(String name) {
        super(name);
    }
Example (cont’d)
    public void testEmptyCollection() {
        Collection collection = new ArrayList();
        assertTrue(collection.isEmpty());
    }
Example (cont’d)
•	To create suite:
    public static Test suite() {
       return new TestSuite(SimpleTest.class);
    }
•	Reflection: Java provides ability to get at “the classes, interfaces, and objects in the current Java Virtual Machine”

Example (cont’d)
    public static void main(String args[]) {
        junit.textui.TestRunner.run(suite());
    }
}
•	Swing GUI available, too
•	From command line:
–	java junit.swingui.TestRunner SimpleTest
Example (cont’d)
•	A couple tests to show failures:
    public void testAddCollection() {
        Collection collection = new ArrayList();
        
        collection.add("Hello, world");
        assertTrue(collection.isEmpty());
    }
Example (cont’d)
    public void testError() {
        Collection collection = new ArrayList();
        
        int x = 1 / collection.size();
        assertTrue(collection.isEmpty());
    }
Example (cont’d)
•	Can modify example to use fixture:
protected void setUp() {
    // remove following from test methods
    collection = new ArrayList();
}
protected void tearDown() {
    collection.clear();
} 
Advice re: unit testing
•	Some things are “too simple” to break
Ex: public Collection getCollection() {
          return collection;
}
•	Difference between testing application vs. testing compiler
•	Testing resources are limited
Testing exceptions
•	Exceptions:
–	Test method includes try … catch …
–	fail(String message); // for when exception should have been raised, but wasn’t
–	JUnit catches uncaught exceptions
•	Reports them as errors
Testing GUI’s
•	A number of extensions to JUnit available:
–	http://www.junit.org/news/extension/gui/index.htm 
–	These tools record a sequence of actions and replay them, allowing you to see what happens
Abbot example
•	At start of test file, need:
import junit.extensions.abbot.*;
import abbot.tester.*;

public class ClassName extends ComponentTestFixture {

Abbot example (continued)
•	 ComponentTester class support methods to trigger GUI actions
private ComponentTester tester;
    protected void setUp() {
        tester = ComponentTester.getTester(ArrowButton.class);
    }
Abbot example (continued)
•	Ex: actionClick() to click on a button
 ArrowButton left = new ArrowButton(ArrowButton.LEFT);
// …
 tester.actionClick(left);