11

I want to do some logging while executing my JUnit test. In JUnit 3.x it was always easy to obtain the name of the currently running test case, no matter how the test case was instantiated:

public void testFoo() throws Exception() {
  String testName = this.getName();
  // [...] do some stuff
}

In JUnit 4 things seem to be not so easy. Does anyone know a solution to this? Is there any option to reflect into the current Runner instance?

mkoeller
  • 4,469
  • 23
  • 30

5 Answers5

10

In JUnit 4.7, you can also get the name of the currently executed test method. May be nice when logging.

Taken from JUnit 4.7 Release Notes (read them here at github) :

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());
    }
}
Sebastian Schuth
  • 9,999
  • 1
  • 20
  • 16
5

OK. I've found another approach [somewhere on the Internet](http://www.nabble.com/What-happened-to-getName()--td23456371.html):

    @RunWith(Interceptors.class) 
    public class NameTest { 
            @Interceptor public TestName name = new TestName(); 

            @Test public void funnyName() { 
                    assertEquals("funnyName", name.getMethodName()); 
            } 
    } 
Grzegorz Oledzki
  • 23,614
  • 16
  • 68
  • 106
  • That seems exactly in the direction I was looking for. I'll give it a try tomorrow. – mkoeller Jul 01 '09 at 17:57
  • Unfortunately, this solution is only going to be released in the upcoming final version of JUnit 4.7 . Meanwhile I'm forced to stick with an earlier version that's included in the customer's framework architecture. However, this is the best answer to the question. – mkoeller Jul 02 '09 at 08:50
  • Where is this Interceptors class? I don't see it in the 4.11 Javadoc – Peter Tseng Dec 14 '12 at 06:04
  • @Peter The answer using the Rule annotation is what is in junit now. – sMoZely Apr 01 '13 at 08:39
4
public class FooTest {
    @Rule
    final public TestRule traceTestWatcher = new TestWatcher() {
        @Override
        protected void starting(Description d) {
            System.out.println(d);
        }
    };

    @Test
    public void testBar() {
        ...
    }

    @Test
    public void testBaz() {
        ...
    }
}
Peter Tseng
  • 13,613
  • 4
  • 67
  • 57
0

What's wrong with:

@Test
public void foo() throws Exception() {
   String testName = this.getName();
   // [...] do some stuff
}

?

Grzegorz Oledzki
  • 23,614
  • 16
  • 68
  • 106
  • In JUnit 4 the test classes no longer extend a common framework class. So there's no inherited method getName any more. – mkoeller Jul 01 '09 at 14:59
  • OK. I still don't get what is the `this.getName() about. How is it different than this.getClass().getName()? (I've found another answer for you) – Grzegorz Oledzki Jul 01 '09 at 15:51
  • 1
    In JUnit 3, TestCase.getName() returns the name of the test method. When you run a JUnit3 test case, multiple instances of your test class are created, each with a different name. See http://junit.sourceforge.net/doc/cookstour/cookstour.htm – NamshubWriter Jul 07 '09 at 05:12
0

I know this is old, but here is a useful (non-junit) method that I put at the top of all my tests.

public static void printTestName(){
    final StackTraceElement[] ste = new Throwable().getStackTrace();
    int buffer = 35 - ste[1].getMethodName().length();
    System.out.println("*******************************************************");
    System.out.println("*            TEST:  " + ste[1].getMethodName() + getBuffer(buffer) + "*");
    System.out.println("*******************************************************");
}

private static String getBuffer(int offset){
    StringBuilder buffer = new StringBuilder("");
    for(int i = 1; i < offset; i++){
        buffer.append(" ");
    }
    return buffer.toString();
}
Half_Duplex
  • 5,102
  • 5
  • 42
  • 58