package org.junit.runners; import java.util.ConcurrentModificationException; import org.junit.internal.runners.InitializationError; import org.junit.internal.runners.TestClassRunner; import org.junit.runner.Description; import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; /** * Provides the current test name, available for the @Test method and @Before and @After methods, just like the default runner should!
(see Test.getName() in JUnit3) * @since JUnit 4 * @author Joshua.Graham@thoughtworks.com * @author based on http://tech.groups.yahoo.com/group/junit/message/18728 * * Another warm, sunny Autumn day in Sydney ends, and I'm making this testable... */ public class NameAwareTestClassRunner extends TestClassRunner { private final static ThreadLocal testClassName = new ThreadLocal(); private final static ThreadLocal testMethodName = new ThreadLocal(); protected static void setName(final String name) { testMethodName.set(extractTestMethodName(name)); testClassName.set(extractTestClassName(name)); } /** * Old-style JUnit 3 TestCase.getName() format * @return package.class.method() */ public static String getName() { return String.format("%s.%s()", getTestClassName(), getTestMethodName()); } /** * JUnit 4 test name format * @return method(package.class) */ public static String getTestName() { return String.format("%s(%s)", getTestMethodName(), getTestClassName()); } public static String getTestMethodName() { return testMethodName.get(); } public static String getTestClassName() { return testClassName.get(); } public NameAwareTestClassRunner(final Class klass) throws InitializationError { super(klass); } @Override public void run(final RunNotifier notifier) { notifier.addListener(new NameListener()); super.run(notifier); } private static String extractTestMethodName(final String name) { if (name != null) { int last = name.lastIndexOf('('); return last < 0 ? name : name.substring(0, last); } return null; } private static String extractTestClassName(final String name) { if (name != null) { int last = name.lastIndexOf('('); return last < 0 ? null : name.substring(last + 1, name.length() - 1); } return null; } private static class NameListener extends RunListener { @Override public void testStarted(final Description description) { setName(description.isTest() ? description.getDisplayName() : null); /* record start of tests, not suites */ } @Override public void testFinished(final Description description) { if (getTestName() != null) { if (getTestName().equals(description.getDisplayName())) { setName(null); } else { throw new ConcurrentModificationException("Test name mismatch. Was " + description.getDisplayName() + " expected " + getTestName()); } } } } }