before/after TestCase with JUnit 3.x
Thursday, August 31st, 2006With Junit 4.x or TestNG, one can define a before/after class callback which will be called before/after the tests within the test class execute. For those of us stuck with JUnit 3.x I have written a simple extension to JUnit TestCase that allows for it.
It is a very simple implementation, counting the number of tests within the test case, and using the information in order to call the beforeTestCase and afterTestCase callbacks. Note, that if running just a single test within the TestCase (as often done with an IDE), the afterTestCase will not be called (which is often ok, since the JVM will shut down). Here is the code:
/** * A simple extension to Junit <code>TestCase</code> allowing for * {@link #beforeTestCase()} and {@link #afterTestCase()} callbacks. * <p/> * Note, the callbacks will only work if running the whole test case * and not just one test. * * @author kimchy */ public class ExtendedTestCase extends TestCase { private static int testCount = 0; private static int totalTestCount = -1; private static boolean disableAfterTestCase = false; protected ExtendedTestCase() { super(); } protected ExtendedTestCase(String name) { super(name); } public void runBare() throws Throwable { Throwable exception = null; if (totalTestCount == -1) { totalTestCount = countTotalTests(); } if (testCount == 0) { beforeTestCase(); } testCount++; try { super.runBare(); } catch (Throwable running) { exception = running; } if (testCount == totalTestCount) { totalTestCount = -1; testCount = 0; if (!disableAfterTestCase) { try { afterTestCase(); } catch (Exception afterTestCase) { if (exception == null) exception = afterTestCase; } } else { disableAfterTestCase = false; } } if (exception != null) throw exception; } protected static void disableAfterTestCase() { disableAfterTestCase = true; } /** * Called before any tests within this test case. * * @throws Exception */ protected void beforeTestCase() throws Exception { } /** * Called after all the tests within the test case * have executed. * * @throws Exception */ protected void afterTestCase() throws Exception { } private int countTotalTests() { int count = 0; Class superClass = getClass(); Vector<String> names = new Vector<String>(); while (Test.class.isAssignableFrom(superClass)) { Method[] methods = superClass.getDeclaredMethods(); for (Method method : methods) { String name = method.getName(); if (names.contains(name)) continue; names.addElement(name); if (isTestMethod(method)) { count++; } } superClass = superClass.getSuperclass(); } return count; } private boolean isTestMethod(Method m) { String name = m.getName(); Class[] parameters = m.getParameterTypes(); Class returnType = m.getReturnType(); return parameters.length == 0 && name.startsWith(“test”) && returnType.equals(Void.TYPE); } }

My name is Shay Banon, the founder of