Java/더 자바, 애플리케이션을 테스트하는 다양한 방법

Junit5 @ExtendWith, @RegisterExtension 확장 모듈

bongveloper 2023. 9. 12. 21:29

Junit5 @ExtendWith, @RegisterExtension 확장 모듈에 대해서 알아보도록 하겠습니다.
이 글은 백기선님 더 자바, 애플리케이션을 테스트하는 다양한 방법을 정리한 글입니다.

더 자바, 애플리케이션을 테스트하는 다양한 방법

 

더 자바, 애플리케이션을 테스트하는 다양한 방법 - 인프런 | 강의

자바 프로그래밍 언어를 사용하고 있거나 공부하고 있는 학생 또는 개발자라면 반드시 알아야 하는 애플리케이션을 테스트하는 다양한 방법을 학습합니다., 그냥 개발자를 넘어 '더 나은 개발

www.inflearn.com

 

@ExtendWith, @RegisterExtension


Junit5의 확장 모듈은 테스트 프레임워크의 기능을 확장하고 새로운 기능을 추가하는 플러그인 또는 라이브러리입니다.
그중

@ExtendWith, @RegisterExtension은 JUnit 5에서 라이프 사이클 관련 인터페이스를 구현해서 적용하는 애노테이션입니다.


@ExtendWith와 @RegisterExtension의 차이


@ExtendWith, @RegisterExtension의 차이는
@ExtendWith는 Extension 구현체 클래스를 선언하여 적용합니다.
@RegisterExtension 인스턴스를 생성해 Extension 구현체를 적용합니다.
@RegisterExtension는 인스턴스를 생성하기 때문에 생성자에 값을 넘겨줄 수 있습니다. 하지만 @ExtendWith은 선언하기만 해서 값을 넘겨줄 수 없습니다.

거기에 properties에 설정하여 자동으로 찾는 방법이 있지만 원하지 않는 테스트에 적용될 수 있어 잘 사용되지는 않습니다.
이 둘의 장점을 보았을 때 @RegisterExtension을 사용하는 것이 정확한 테스트하기에 용이하는 걸 알 수 있습니다.

@RegisterExtension


인스턴스를 생성해 Extension 구현체를 적용합니다.

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

//@ExtendWith(FindSlowTestExtension.class) 선언적으로 가능
public class ExtensionTest {

	@RegisterExtension
	FindSlowTestExtension findSlowTestExtension = new FindSlowTestExtension(1000L);

    @DisplayName("확장 @SlowTest 테스트")
    @SlowTest
    void extensionSlowTest() throws InterruptedException {
        Thread.sleep(1005);
        System.out.println("확장 @SlowTest 테스트");
    }

    @Test
    @DisplayName("확장 테스트")
    void extensionTest() throws InterruptedException {
        Thread.sleep(1005);
        System.out.println("확장 테스트");
    }
}
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

public class FindSlowTestExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {

    /**
     * BeforeTestExecutionCallback, AfterTestExecutionCallback 인터페이스를 구현해서 확장할 수 있다.
     *
     */
    private long THRESHOLD;

    public FindSlowTestExtension(long THRESHOLD) {
        this.THRESHOLD = THRESHOLD;
    }

    //실행 전
    @Override
    public void beforeTestExecution(ExtensionContext context) {
        ExtensionContext.Store store = getStore(context);
        store.put("START_TIME", System.currentTimeMillis());
    }

    //실행 후
    @Override
    public void afterTestExecution(ExtensionContext context){
        //리플렉션으로 메소드의 애노테이션을 가져올 수 있다.
        SlowTest annotation = context.getRequiredTestMethod().getAnnotation(SlowTest.class);
        String methodName = context.getRequiredTestMethod().getName();
        ExtensionContext.Store store = getStore(context);

        Long startTime = store.remove("START_TIME", long.class);
        long duration = System.currentTimeMillis() - startTime;

        if(duration > THRESHOLD && annotation == null){
            System.out.printf("[%s]가 @SlowTest 애노테이션이 있는지 메소드를 확인해주세요.\n",methodName);
        }
    }

    private static ExtensionContext.Store getStore(ExtensionContext context) {
        String className = context.getRequiredTestClass().getName(); //메소드 정보 가져오기
        String methodName = context.getRequiredTestMethod().getName(); //메소드 정보 가져오기
        //store는 데이터를 넣고 뺄수 있다.
        ExtensionContext.Store store = context.getStore(ExtensionContext.Namespace.create(className, methodName));
        return store;
    }
}

먼저 FindSlowTestExtension 구현체를 보겠습니다.
ExtensionContext에서는 테스트의 정보를 알 수 있고 Store를 통해 데이터를 넣거나 뺄 수 있습니다.

지정한 시간이상 테스트가 지속되면서 @SlowTest 애노테이션이 없는 테스트의 경우 @SlowTest 에노테이션을 확인하라는 메시지를 출력하는 로직으로 테스트를 진행하였습니다.
store에 시작시각을 넘겨주고 그 사이를 측정해 테스트 시간을 구하는 로직이고
Java 리플랙션으로 메서드의 애노테이션 정보를 받아와 @SlowTest가 있는지 확인하는 로직입니다.

해당 로직을 실행해 보면

@SlowTest가 붙은 테스트에는 메시지가 나오지 않는것을 볼 수 있고
@SlowTest가 붙지 않은 테스트에는 메세지가 나오는 것을 볼 수 있습니다.

@ExtendWith, @RegisterExtension에 대해서 알아보았습니다.
이 확장 모듈은 @BeforeEach나 @AfterEach의 기능과 매우 유사합니다. 유사하지만 거기에 더 많은 기능을 사용할 수 있다는 점에서 더욱 유용한 확장 모듈로 생각됩니다.
@ExtendWith, @RegisterExtension 확장 모듈을 마치도록 하겠습니다. 감사합니다.

 

https://github.com/kibongcoders/junit5

 

GitHub - kibongcoders/junit5

Contribute to kibongcoders/junit5 development by creating an account on GitHub.

github.com

 

 

출처 :

더 자바, 애플리케이션을 테스트하는 다양한 방법

 

더 자바, 애플리케이션을 테스트하는 다양한 방법 - 인프런 | 강의

자바 프로그래밍 언어를 사용하고 있거나 공부하고 있는 학생 또는 개발자라면 반드시 알아야 하는 애플리케이션을 테스트하는 다양한 방법을 학습합니다., 그냥 개발자를 넘어 '더 나은 개발

www.inflearn.com