4.8 Organizing Tests into Test Suites

4.8.1 Problem

You want to organize multiple tests into a suite of tests, all of which run at once.

4.8.2 Solution

JUnit does this automatically for each test case. You can construct an instance of junit.framework.TestSuite to create your own suites manually.

4.8.3 Discussion

When you use the text or graphical test runner, JUnit looks for the following method in your test case:[5]

[5] The Ant junit task also looks for the suite() method.

public static Test suite(  ) { ... }

If the method is not found, JUnit uses reflection to automatically locate all testXXX( ) methods in your test case, adding them to a suite of tests. It then runs all tests in this suite. You can duplicate the default suite( ) behavior as follows:

public class TestGame extends TestCase {
    ...
    public static Test suite(  ) {
        return new TestSuite(TestGame.class);
    }
}

By passing the TestGame.class object to the TestSuite constructor, you are telling JUnit to locate all of the testXXX( ) methods in that class and add them to the suite. This code does not do anything above and beyond what JUnit does automatically, but there are more interesting ways to use the TestSuite class. For instance, you can add individual tests to only run certain tests, or you can control the order in which they are executed:

public static Test suite(  ) {
    TestSuite suite = new TestSuite(  );
    // To use this idiom, you must define the String constructor in your 
    // TestGame class. Remember that JUnit 3.8 made that constructor optional.
    suite.addTest(new TestGame("testCreateFighter"));
    suite.addTest(new TestGame("testSameFighters"));
    return suite;
}

Or, even better, you can compose multiple suites into other suites. You might recognize this as the Composite design pattern.[6]

[6] See Gamma et al., Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley).

For example:

public static Test suite(  ) {
    TestSuite suite = new TestSuite(TestGame.class);
    suite.addTest(new TestSuite(TestPerson.class));
    return suite;
}

Now, when you run this test case, you will run all tests from both TestGame and TestPerson.

4.8.4 See Also

Recipe 4.12 provides suggestions for organizing test suites.