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 .
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() {
}
}
대신 이것을 시도하십시오 :
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 코드는 실행되지 않습니다.
복잡한 방법은 org.junit.runners.BlockJUnit4ClassRunner를 서브 클래 싱하여 자신의 러너를 만드는 것입니다.
그런 다음 다음과 같은 작업을 수행 할 수 있습니다.
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에는 테스트 케이스가 자체 이름을 얻는 기본 (out-of-the-box) 메커니즘이 없습니다 (설정 및 해제 중 포함).
String testName = null;
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (int i = trace.length - 1; i > 0; --i) {
StackTraceElement ste = trace[i];
try {
Class<?> cls = Class.forName(ste.getClassName());
Method method = cls.getDeclaredMethod(ste.getMethodName());
Test annotation = method.getAnnotation(Test.class);
if (annotation != null) {
testName = ste.getClassName() + "." + ste.getMethodName();
break;
}
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
}
이전 의견과 추가 고려 사항을 바탕으로 다음과 같이 JUnit 테스트 방법에서 사용할 수있는 TestWather 확장을 만들었습니다.
public class ImportUtilsTest {
private static final Logger LOGGER = Logger.getLogger(ImportUtilsTest.class);
@Rule
public TestWatcher testWatcher = new JUnitHelper(LOGGER);
@Test
public test1(){
...
}
}
테스트 도우미 클래스는 다음입니다.
public class JUnitHelper extends TestWatcher {
private Logger LOGGER;
public JUnitHelper(Logger LOGGER) {
this.LOGGER = LOGGER;
}
@Override
protected void starting(final Description description) {
LOGGER.info("STARTED " + description.getMethodName());
}
@Override
protected void succeeded(Description description) {
LOGGER.info("SUCCESSFUL " + description.getMethodName());
}
@Override
protected void failed(Throwable e, Description description) {
LOGGER.error("FAILURE " + description.getMethodName());
}
}
즐겨!
@ClassRule
public static TestRule watchman = new TestWatcher() {
@Override
protected void starting( final Description description ) {
String mN = description.getMethodName();
if ( mN == null ) {
mN = "setUpBeforeClass..";
}
final String s = StringTools.toString( "starting..JUnit-Test: %s.%s", description.getClassName(), mN );
System.err.println( s );
}
};
테스트 데이터 세트에서 테스트 메소드 이름을 분리하는 것이 좋습니다. 리소스에서 테스트 데이터 세트를로드 / 캐시하는 DataLoaderFactory 클래스를 모델링 한 다음 테스트 케이스 캠에서 테스트 케이스에 대한 테스트 데이터 세트를 리턴하는 인터페이스 메소드를 호출합니다. 테스트 방법 이름에 테스트 데이터를 연결하면 테스트 데이터를 한 번만 사용할 수 있다고 가정합니다. 대부분의 경우 비즈니스 로직의 다양한 측면을 확인하기 위해 여러 테스트에서 동일한 테스트 데이터를 사용하는 것이 좋습니다.
사용이 달성 할 수 Slf4j및TestWatcher
private static Logger _log = LoggerFactory.getLogger(SampleTest.class.getName());
@Rule
public TestWatcher watchman = new TestWatcher() {
@Override
public void starting(final Description method) {
_log.info("being run..." + method.getMethodName());
}
};
JUnit 5 TestInfo에서 JUnit 4의 TestName 규칙을 대체하는 역할을합니다.
설명서에서 :
TestInfo는 현재 테스트 또는 컨테이너에 대한 정보를 @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, @BeforeEach, @AfterEach, @BeforeAll 및 @AfterAll 메소드에 주입하는 데 사용됩니다.
현재 실행 된 테스트의 메소드 이름을 검색하려면, 두 가지 옵션이 있습니다 : String TestInfo.getDisplayName()와 Method TestInfo.getTestMethod().
TestInfo.getDisplayName()테스트 방법 기본 표시 이름이이므로 현재 테스트 방법의 이름 만 검색하는 것만으로는 충분하지 않을 수 있습니다 methodName(TypeArg1, TypeArg2, ... TypeArg3).
메소드 이름을 복제 @DisplayName("..")하는 것은 좋은 생각이 아닙니다.
대안 TestInfo.getTestMethod()으로 Optional<Method>객체 를 반환 할 수 있습니다 .
검색 방법이 테스트 방법 내에서 사용되는 경우 Optional랩핑 된 값 을 테스트 할 필요조차 없습니다 .
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.Test;
@Test
void doThat(TestInfo testInfo) throws Exception {
Assertions.assertEquals("doThat(TestInfo)",testInfo.getDisplayName());
Assertions.assertEquals("doThat",testInfo.getTestMethod().get().getName());
}
참고 URL : https://stackoverflow.com/questions/473401/get-name-of-currently-executing-test-in-junit-4
'development' 카테고리의 다른 글
| Android : 여러 줄의 EditText (텍스트 영역)에 대한 세로 정렬 (0) | 2020.04.16 |
|---|---|
| div의 내용을 포장하지 않는 방법? (0) | 2020.04.16 |
| 디렉토리에서 최신 수정 파일을 재귀 적으로 찾는 방법은 무엇입니까? (0) | 2020.04.16 |
| Xcode 8 / Swift 3 :“UIViewController 유형의 표현? (0) | 2020.04.16 |
| Selenium에서 Enter / Return 키 입력 (0) | 2020.04.16 |