본문 바로가기

Java/Test

(Test) JUit5 확장모델

JUnit 4의 확장 모델은 @RunWith(Runner), TestRule, MethodRule.

JUnit 5의 확장 모델은 단 하나, Extension.

 

https://junit.org/junit5/docs/current/user-guide/#extensions

 

JUnit 5 User Guide

Although the JUnit Jupiter programming model and extension model will not support JUnit 4 features such as Rules and Runners natively, it is not expected that source code maintainers will need to update all of their existing tests, test extensions, and cus

junit.org


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

실행결과 - slowTest에 1초이상 주었을때는 뜨지 않는다. 이미 @slowTest이 있기 때문

 

이 방법의 단점은

애노테이션으로 등록할 경우 코드의 커스터마이징이 불가하다는 점이다.

예를 들자면

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

 

ServiceLoader (Java SE 11 & JDK 11 )

A facility to load implementations of a service. A service is a well-known interface or class for which zero, one, or many service providers exist. A service provider (or just provider) is a class that implements or subclasses the well-known interface or c

docs.oracle.com

 

junit.jupiter.extensions.autodetection.enabled = true

코드참조

https://github.com/mike6321/PURE_JAVA/tree/master/HowToTest/inflearn-the-java-test/src

 

mike6321/PURE_JAVA

Contribute to mike6321/PURE_JAVA development by creating an account on GitHub.

github.com

 

'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