JUnit 4의 확장 모델은 @RunWith(Runner), TestRule, MethodRule.
JUnit 5의 확장 모델은 단 하나, Extension.
https://junit.org/junit5/docs/current/user-guide/#extensions
Lifecycle callBak을 이용한 실행하는데 오래걸리는 Test를 찾아서 메세지를 출력하는 Extention 만들기
- 실행이 오래걸리는데 @SlowTest 가 붙어있지 않다면 붙이라고 권장하는 메세지
1. BeforeTestExecutionCallback, AfterTestExecutionCallback를 구현 하는 FindSlowTestExtention 클래스
public class FindSlowTestExtention implements BeforeTestExecutionCallback, AfterTestExecutionCallback {
@Override
public void afterTestExecution(ExtensionContext extensionContext) throws Exception {
}
@Override
public void beforeTestExecution(ExtensionContext extensionContext) throws Exception {
}
}
여기서 ExtensionContext은 값을 저장하고 빼는 getStore를 제공한다.
2. Test 클래스와 Test 메서드를 불러와서 ExtentionContext에 시작 시간을 저장
@Override
public void beforeTestExecution(ExtensionContext extensionContext) throws Exception {
// extensionContext : 값을 저장하는 store
String testClassName = extensionContext.getRequiredTestClass().getName();
String testMethodName = extensionContext.getRequiredTestMethod().getName();
ExtensionContext.Store store = extensionContext.getStore(ExtensionContext.Namespace.create(testClassName, testMethodName));
store.put("START TIME", System.currentTimeMillis());
}
3. 리펙토링
@Override
public void afterTestExecution(ExtensionContext extensionContext) throws Exception {
// extensionContext : 값을 저장하는 store
ExtensionContext.Store store = getStore(extensionContext);
store.put("START TIME", System.currentTimeMillis());
}
private ExtensionContext.Store getStore(ExtensionContext extensionContext) {
String testClassName = extensionContext.getRequiredTestClass().getName();
String testMethodName = extensionContext.getRequiredTestMethod().getName();
return extensionContext.getStore(ExtensionContext.Namespace.create(testClassName, testMethodName));
}
4. afterTestExecution에서 before와 동일하게 처리하되 저장한 값(시간) 을 꺼내와 특정시간 이상이면 메세지를 출력
- slowTest 애노테이션이 없는 경우에만 해당
@Override
public void afterTestExecution(ExtensionContext extensionContext) throws Exception {
Method testMethod = extensionContext.getRequiredTestMethod();
SlowTest annotation = testMethod.getAnnotation(SlowTest.class);
String testMethodName = testMethod.getName();
ExtensionContext.Store store = getStore(extensionContext);
Long start_time = store.remove("START TIME", long.class);
Long duration = System.currentTimeMillis() - start_time;
if(duration > THRESHOLD && annotation ==null) {
System.out.printf("Pleas consider mark method [%s] with @SlowTEST \n", testMethodName);
}
}
이제 작성한 Extention을 적용할 차례
선언적인 등록 @ExtendWith
- @ExtentionWith 작성
@ExtendWith(FindSlowTestExtention.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class StudyTest {
- 1초 이상 걸리게 설정
@Order(2)
@FastTest
@DisplayName("주누의 개인공부 시간 fast")
void create_new_study() throws InterruptedException {
Thread.sleep(1005L);
System.out.println(this);
System.out.println(val++);
}
이 방법의 단점은
애노테이션으로 등록할 경우 코드의 커스터마이징이 불가하다는 점이다.
예를 들자면
private static long THRESHOLD = 1000L;
를 호출할때 마다 다르게 주고 싶지만
private long THRESHOLD;
public FindSlowTestExtention(long THRESHOLD) {
this.THRESHOLD = THRESHOLD;
}
@ExtendWith(FindSlowTestExtention.class) 이러한 식으로 파라미터를 어떻게 줄 것인가?
프로그래밍 등록 @RegisterExtension
인스턴스를 만들어서 등록
@RegisterExtension
static FindSlowTestExtention findSlowTestExtention = new FindSlowTestExtention(1000L);
자동 등록 자바 ServiceLoader 이용
자동 등록 자바 ServiceLoader 이용
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html
junit.jupiter.extensions.autodetection.enabled = true
코드참조
https://github.com/mike6321/PURE_JAVA/tree/master/HowToTest/inflearn-the-java-test/src
'Java > Test' 카테고리의 다른 글
(Test) Mockito 란? (0) | 2020.01.01 |
---|---|
(Test) JUit5 - JUnit4 Migration (0) | 2020.01.01 |
(Test) JUnit5 - junitplatform.properties (0) | 2020.01.01 |
(Test) JUnit 5 테스트 순서 (0) | 2019.12.31 |
(Test) JUnit 5 테스트 인스턴스 (0) | 2019.12.30 |