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에는 테스트 케이스가 자체 이름을 얻을 수있는 기본 제공 메커니즘이 없습니다 (설정 및 해제 중 포함).