Test-wide Setup and Tear Down of JUnit Tests
JUnit 4.0 introduces the @BeforeClass annotation, providing a way to run a class-wide setup method before any of the tests in that class are run. The analogous @AfterClass annotation allows for tear down of those fixtures. I work on a project that hasn’t yet upgraded to JUnit 4.0, and although less widely publicized, it is possible to accomplish the same thing with 3.8.x.
Think before doing this. Tests should be independent of one another. If your tests share fixtures, side effects from one test could affect the results of others. Sometimes, however, a test fixture is just too expensive to set up and tear down with every test. In my case, I needed to set up a database and import a substantial quantity of data. Doing this for every test would’ve made the suite prohibitively slow.
The TestSetup class makes test-wide setup and tear down possible in JUnit 3.8.x. Consider the following class:
package com.burningvoid.jexample;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
public class ExampleTestCase extends TestCase {
public void setUp() {
System.out.println("Per Test Case Setup");
}
public void tearDown() {
System.out.println("Per Test Case Teardown");
}
public void testA() {
System.out.println("Test A");
}
public void testB() {
System.out.println("Test B");
}
public static Test suite() {
return new TestSuite(ExampleTestCase.class);
}
public static void main(String[] args) {
TestRunner.run(suite());
}
}
If I run this class, the setUp and tearDown methods run once before each test, producing output of:
.Per Test Case Setup
Test A
Per Test Case Teardown
.Per Test Case Setup
Test B
Per Test Case Teardown
For those accustomed to IDE support for JUnit, the periods in the output are due to the text JUnit test runner. It prints a period for each test.
Ok, now change the suite() method to the following:
public static Test suite() {
TestSuite ts = new TestSuite();
ts.addTestSuite(ExampleTestCase.class);
return new ExampleTestSetup(ts);
}
This requires the addition of another class.
package com.burningvoid.jexample;
import junit.extensions.TestSetup;
import junit.framework.Test;
public class ExampleTestSetup extends TestSetup {
public ExampleTestSetup(Test test) {
super(test);
}
public void setUp() {
System.out.println("Test-wide setup");
}
public void tearDown() {
System.out.println("Test-wide teardown");
}
}
The TestSetup decorator’s setUp and tearDown methods are called before and after all the tests in the suite, resulting in the following output.
Test-wide setup
.Per Test Case Setup
Test A
Per Test Case Teardown
.Per Test Case Setup
Test B
Per Test Case Teardown
Test-wide teardown
If you need test setup and tear down that covers more than one class, simply create a top level test suite that collects all of your test classes into one decorated suite, such as:
public static Test suite() {
TestSuite ts = new TestSuite();
ts.addTestSuite(ExampleTestCase.class);
ts.addTestSuite(SomeOtherTestCase.class);
ts.addTestSuite(YetAnotherTestCase.class);
return new ExampleTestSetup(ts);
}
As far as I know, the @BeforeClass and @AfterClass mechanisms aren’t quite as flexible, in that they only apply to a single class, and thus can’t be applied to an entire suite. I say this not having used JUnit 4.0 yet, though, so please correct me if I’m incorrect about this.







