Chapter 8. Making your TestCases Test-Runner-Friendly

Test Runners execute Tests-- TestSuites and TestCases. They run Test.run() just like you did in our example, but they also collect, summarize, and format the results nicely. There are also graphical test runners. Test Runner in this sense is not a real class name. By Test Runner, I mean a Java class that can run JUnit tests and collect, summarize, and format the results. The JUnit Test Runners that I know extend junit.runner.BaseTestRunner. This is what your tests will look like if you use the JUnit Swing Test Runner.

A successful Swing TestRunner.
A failed Swing TestRunner run.

Your current objective is to learn the best way to tell the Test Runners which TestSuites to run. There are many different methods-- nearly all of these methods are either ugly or inflexible (the former requiring you to implement inner classes with methods inside every single test method, the latter requiring that your test methods follow a naming convention and be run in a specific order with no omissions).

The one method that is extremly simple and so flexible that you will never need another method, is to just create a static method TestSuite.suite() that returns the TestSuite that you want run. You give the name of this TestCase class to a Test Runner and it will do exactly what you want it to do.

If a TestCase class has a suite() method, then when you run a Test Runner on that TestCase, it will run

    setUp();
    yourMethod();
    tearDown();

for each elemental test method in the TestSuite that your suite() method returns. Your suite() method creates and populates a new TestSuite object exacly as described in the Class junit.framework.TestSuite chapter, and returns it.

This method is very flexible because you can specify any subset of your methods in any sequence you wish. The methods can even come from different files. (Keep in mind that the setUp() and tearDown() methods for each test method come from the file containing the test method). You can name the methods as you wish, but they can't take any input parameters.

Here's exactly what you need to do to make a TestCase class that Test Runners can work with. You just add a (String) constructor to your TestCase subclass (because you need to call new YourTestCase(String) next). Then implement suite() by populating and returning a TestSuite.

    public SMTPTest(String s) { super(s); }

    static public junit.framework.Test suite() {
        junit.framework.TestSuite newSuite = new junit.framework.TestSuite();
        newSuite.addTest(new SMTPTest("testJavaMail"));
        newSuite.addTest(new SMTPTest("testNOOP"));
        newSuite.addTest(new SMTPTest("testSMTPMessage"));
        return newSuite;
    };