[java] JUnit 4에서 현재 실행중인 테스트 이름 가져 오기

JUnit 3에서 다음과 같이 현재 실행중인 테스트 이름을 얻을 수 있습니다.

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

“현재 테스트는 testSomething”입니다.

JUnit 4에서 즉시 사용 가능한 간단한 방법이 있습니까?

배경 : 테스트 이름 만 인쇄하고 싶지는 않습니다. 테스트와 이름이 같은 리소스에 저장된 테스트 특정 데이터를로드하고 싶습니다. 당신은 구성 과 그 이상에 대한 관습을 알고 있습니다.



답변

JUnit 4.7은 TestName-Rule을 사용하는 것처럼 보이는이 기능을 추가했습니다 . 다음과 같이 메소드 이름이 표시됩니다.

import org.junit.Rule;

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());
    }
}


답변

JUnit 4.9.x 이상

JUnit 4.9부터 클래스는 호출 TestWatchman이 있는 클래스를 위해 더 이상 사용되지 않습니다 TestWatcher.

@Rule
public TestRule watcher = new TestWatcher() {
   protected void starting(Description description) {
      System.out.println("Starting test: " + description.getMethodName());
   }
};

참고 : 포함 클래스를 선언해야합니다 public.

JUnit 4.7.x-4.8.x

다음 접근법은 클래스의 모든 테스트에 대한 메소드 이름을 인쇄합니다.

@Rule
public MethodRule watchman = new TestWatchman() {
   public void starting(FrameworkMethod method) {
      System.out.println("Starting test: " + method.getName());
   }
};


답변

JUnit 5 이상

JUnit 5 에서는 TestInfo테스트 메소드에 제공하는 테스트 메타 데이터를 단순화 하는 것을 주입 할 수 있습니다 . 예를 들면 다음과 같습니다.

@Test
@DisplayName("This is my test")
@Tag("It is my tag")
void test1(TestInfo testInfo) {
    assertEquals("This is my test", testInfo.getDisplayName());
    assertTrue(testInfo.getTags().contains("It is my tag"));
}

더보기 : JUnit 5 사용자 안내서 , TestInfo javadoc .


답변

대신 이것을 시도하십시오 :

public class MyTest {
        @Rule
        public TestName testName = new TestName();

        @Rule
        public TestWatcher testWatcher = new TestWatcher() {
            @Override
            protected void starting(final Description description) {
                String methodName = description.getMethodName();
                String className = description.getClassName();
                className = className.substring(className.lastIndexOf('.') + 1);
                System.err.println("Starting JUnit-test: " + className + " " + methodName);
            }
        };

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

        @Test
        public void testB() {
                assertEquals("testB", testName.getMethodName());
        }
}

결과는 다음과 같습니다.

Starting JUnit-test: MyTest testA
Starting JUnit-test: MyTest testB

참고 : 테스트가 TestCase 의 하위 클래스 인 경우에는 작동하지 않습니다 ! 테스트는 실행되지만 @Rule 코드는 실행되지 않습니다.


답변

SLF4J (Simple Logging Facade for Java) 사용은 매개 변수화 된 메시지를 사용하여 깔끔하게 개선되었습니다. SLF4J를 JUnit 4 규칙 구현과 결합하면보다 효율적인 테스트 클래스 로깅 기술을 제공 할 수 있습니다.

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.rules.TestWatchman;
import org.junit.runners.model.FrameworkMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggingTest {

  @Rule public MethodRule watchman = new TestWatchman() {
    public void starting(FrameworkMethod method) {
      logger.info("{} being run...", method.getName());
    }
  };

  final Logger logger =
    LoggerFactory.getLogger(LoggingTest.class);

  @Test
  public void testA() {

  }

  @Test
  public void testB() {

  }
}


답변

복잡한 방법은 org.junit.runners.BlockJUnit4ClassRunner를 서브 클래 싱하여 자신의 Runner를 작성하는 것입니다.

그런 다음 다음과 같은 작업을 수행 할 수 있습니다.

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);
    }
}

그런 다음 각 테스트 클래스마다 @RunWith (NameAwareRunner.class) 주석을 추가해야합니다. 또는 매번 기억하지 않으려면 테스트 수퍼 클래스에 주석을 넣을 수 있습니다. 물론 이것은 러너 선택을 제한하지만 허용 될 수 있습니다.

또한 현재 테스트 이름을 러너에서 프레임 워크로 가져 오는 데 약간의 쿵푸가 필요할 수 있지만 최소한 이름을 얻습니다.


답변

JUnit 4에는 테스트 케이스가 자체 이름을 얻을 수있는 기본 제공 메커니즘이 없습니다 (설정 및 해제 중 포함).