views:

3081

answers:

5

In JUnit 3, I could get the name of the currently running test like this:

public class MyTest extends TestCase
{
    public void testSomething()
    {
        System.out.println("Current test is " + getName());
        ...
    }
}

which would print "Current test is testSomething".

Is there any out-of-the-box or simple way to do this in JUnit 4?

Background: Obviously, I don't want to just print the name of the test. I want to load test-specific data that is stored in a resource with the same name as the test. You know, convention over configuration and all that.

Thanks!

+5  A: 

JUnit 4 does not have any out-of-the-box mechanism for a test case to get it’s own name (including during setup and teardown).

cordellcp3
Is there an not-out-of-the-box mechanism out there other than inspecting the stack?
Dave Ray
A: 

Most likely, Bill the Lizard is right. In case it still doesn't work out, you could extract the test name from the stack dump of the current thread (Thread.currentThread().getStackTrace()) -- rather hacky, but maybe the end justifies the means :)

netzwerg
A: 

I'd suggest you decouple the test method name from your test data set. I would model a DataLoaderFactory class which loads/caches the sets of test data from your resources, and then in your test case cam call some interface method which returns a set of test data for the test case. Having the test data tied to the test method name assumes the test data can only be used once, where in most case i'd suggest that the same test data in uses in multiple tests to verify various aspects of your business logic.

emeraldjava
+2  A: 

A convoluted way is to create your own Runner by subclassing org.junit.runners.BlockJUnit4ClassRunner.

You can then do something like this:

public class NameAwareRunner extends BlockJUnit4ClassRunner {

    public NameAwareRunner(Class<?> aClass) throws InitializationError {
        super(aClass);
    }

    @Override
    protected Statement methodBlock(FrameworkMethod frameworkMethod) {
        System.err.println(frameworkMethod.getName());
        return super.methodBlock(frameworkMethod);
    }
}

Then for each test class, you'll need to add a @RunWith(NameAwareRunner.class) annotation. Alternatively, you could put that annotation on a Test superclass if you don't want to remember it every time. This, of course, limits your selection of runners but that may be acceptable.

Also, it may take a little bit of kung fu to get the current test name out of the Runner and into your framework, but this at least gets you the name.

+17  A: 

JUnit 4.7 added this feature it seems:

Announcement, Descrption of new features

Looks like this will get you the method name:

public class NameRuleTest {
    @Rule public TestName name = new TestName();

    @Test public void testA() {
     assertEquals("testA", name.getMethodName());
    }

    @Test public void testB() {
     assertEquals("testB", name.getMethodName());
    }
}
FroMage
import org.junit.Rule;
jm
Also note that TestName is not available in @before :(See: http://old.nabble.com/@Rule-TestName-not-available-in-@Before-methods...-td25198691.html
jm
Apparently newer versions of JUnit execute `@Rule` before `@Before` - I'm new to JUnit and was depending on `TestName` in my `@Before` without any difficulties.
MightyE