junit suite wide setup (not @BeforeClass)

Problem

How do I run setup/teardown for my whole suite, not just one class/test?

Impact of Problem

JUnit offers @Before to run a method before each test and @BeforeClass to run a method once before a class.  For a small suite, @BeforeClass may be enough.  For a large integration test suite, setting up the database is a common task that should be done once for scores of tests.  Having everything in one class is not optimal.  Nor is manually listing all the tests.

Requirements

  1. Continue being able to use ClasspathSuite to gather tests in a subdirectory at runtime.
  2. Run a method before the first of these tests is run
  3. Run a method after the last of these tests is run
  4. Take advantage of JUnit’s runner for running all the tests

Solution

package com.javaranch.test.functional;

import static org.junit.extensions.cpsuite.SuiteType.*;

import org.junit.extensions.cpsuite.*;
import org.junit.extensions.cpsuite.ClasspathSuite.*;
import org.junit.runner.*;

// use cpsuite to dynamically list out tests
@RunWith(ClasspathSuite.class)
@ClassnameFilters( { "com.javaranch.*test.*Test", "net.jforum.*test.*Test" })
// include in case have a parameterized test case
@SuiteTypes( { RUN_WITH_CLASSES, TEST_CLASSES, JUNIT38_TEST_CLASSES })
public class All_JForum_Functional_Tests {
public static void main(String[] args) throws Exception {
setUp();
JUnitCore.main("com.javaranch.test.functional.All_JForum_Functional_Tests");
tearDown();
}

private static void setUp() {
// create the database
}

private static void tearDown() {
// destroy the database
}
}

If you’ve been reading my blog, you’ll know I am doing this to integration test the back end of JavaRanch’s JForum install.  I started by cloning a database and have now moved on to the integration test framework.  Next I will describe the actual database setup.