ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JUnit] JUnit5 @Tag 를 이용한 필터링 및 그룹만들기
    IT/JAVA | Spring 2023. 3. 12. 14:31

    Junit5의 요약된 기초지식에 대한 내용은 아래에서 확인 가능하다.

    2023.02.18 - [IT/JAVA | Spring] - [JUnit] JUnit5 기초지식 정리( 설정, annotation, assertions )

     

    [JUnit] JUnit5 기초지식 정리( 설정, annotation, assertions )

    java 개발자가 가장 많이 사용하는 테스트 프레임워크 JUnit에 대한 기초지식 많은 개발 방법론이 있지만 TDD의 핵심인 Test Code 작성을 위한 프레임워크 중 java 개발자들이 가장 많이 이용하는 프레

    kangyb.tistory.com

    JUnit5 기초지식 annotation 정리 1

    2023.02.25 - [IT/JAVA | Spring] - [JUnit] JUnit5 기초지식 annotation 정리

     

    [JUnit] JUnit5 기초지식 annotation 정리

    Junit5의 요약된 기초지식에 대한 내용은 아래에서 확인 가능하다. 2023.02.18 - [IT/JAVA | Spring] - [JUnit] JUnit5 기초지식 정리( 설정, annotation, assertions ) [JUnit] JUnit5 기초지식 정리( 설정, annotation, assertions

    kangyb.tistory.com

     

    Junit5 User guide에서 확인 가능한 annotation은 아래와 같이 있다.

     

    JUnit Jupiter는 테스트 구성 및 프레임워크 확장을 위해 다음 주석을 지원합니다.

    달리 명시되지 않는 한 모든 핵심 주석은 junit-jupiter-api 모듈 의 패키지에 있습니다.

    annotation 설명
    @Test
    메서드가 테스트 메서드임을 나타냅니다. JUnit 4의 @Test 주석과 달리 JUnit Jupiter의 테스트 확장은 자체 전용 주석을 기반으로 작동하므로 이 주석은 속성을 선언하지 않습니다. 이러한 메서드는 재정의하지 않는 한 상속됩니다.
    @ParameterizedTest
    메서드가 매개 변수가 있는 테스트임을 나타냅니다. 이러한 메서드는 재정의하지 않는 한 상속됩니다.
    @RepeatedTest
    메서드가 반복 테스트를 위한 테스트 템플릿임을 나타냅니다. 이러한 메서드는 재정의하지 않는 한 상속됩니다.
    @TestFactory
    메서드가 동적 테스트를 위한 테스트 팩터리임을 나타냅니다. 이러한 메서드는 재정의하지 않는 한 상속됩니다.
    @TestTemplate
    메서드는 등록된 공급자가 반환한 호출 컨텍스트 수에 따라 여러 번 호출되도록 설계된 테스트 사례의 템플릿임을 나타냅니다. 이러한 메서드는 재정의하지 않는 한 상속됩니다.
    @TestClassOrder
    주석이 달린 테스트 클래스의 @Nested 테스트 클래스에 대한 테스트 클래스 실행 순서를 구성하는 데 사용됩니다. 이러한 주석은 상속됩니다
    @TestMethodOrder
    주석이 달린 테스트 클래스에 대한 테스트 메서드 실행 순서를 구성하는 데 사용됩니다. JUnit 4의 @FixMethodOrder와 유사합니다. 이러한 주석은 상속됩니다.
    @TestInstance
    주석이 달린 테스트 클래스의 테스트 인스턴스 수명 주기를 구성하는 데 사용됩니다. 이러한 주석은 상속됩니다.
    @DisplayName
    테스트 클래스 또는 테스트 메서드에 대한 사용자 지정 표시 이름을 선언합니다. 이러한 주석은 상속되지 않습니다.
    @DisplayNameGeneration
    테스트 클래스에 대한 사용자 지정 표시 이름 생성기를 선언합니다. 이러한 주석은 상속됩니다.
    @BeforeEach
    주석이 달린 메서드는 현재 클래스의 각 @Test, @RepeatedTest, @ParameterizedTest 또는 @TestFactory 메서드 전에 실행되어야 함을 나타냅니다. JUnit 4의 @Before와 유사합니다. 이러한 메서드는 재정의되거나 대체되지 않는 한 상속됩니다(즉, Java의 가시성 규칙에 관계없이 서명에 따라 대체됨).
    @AfterEach
    주석이 달린 메서드는 현재 클래스의 각 @Test, @RepeatedTest, @ParameterizedTest 또는 @TestFactory 메서드 후에 실행되어야 함을 나타냅니다. JUnit 4의 @After와 유사합니다. 이러한 메서드는 재정의되거나 대체되지 않는 한 상속됩니다(즉, Java의 가시성 규칙에 관계없이 서명에 따라 대체됨).
    @BeforeAll
    현재 클래스의 모든 @Test, @RepeatedTest, @ParameterizedTest 및 @TestFactory 메서드보다 먼저 주석이 달린 메서드를 실행해야 함을 나타냅니다. JUnit 4의 @BeforeClass와 유사합니다. 이러한 메서드는 상속되거나, 숨겨지거나, 재정의되거나, 대체되지 않는 한(즉, Java의 가시성 규칙에 관계없이 서명만을 기반으로 대체됨) "클래스별" 테스트 인스턴스 수명 주기가 사용되지 않는 한 static이어야 합니다.
    @AfterAll
    주석이 달린 메서드는 현재 클래스의 모든 @Test, @RepeatedTest, @ParameterizedTest 및 @TestFactory 메서드 후에 실행되어야 함을 나타냅니다. JUnit 4의 @AfterClass와 유사합니다. 이러한 메서드는 상속되거나, 숨겨지거나, 재정의되거나, 대체되지 않는 한(즉, Java의 가시성 규칙에 관계없이 서명만을 기반으로 대체됨) "클래스별" 테스트 인스턴스 수명 주기가 사용되지 않는 한 static이어야 합니다.
    @Nested
    주석이 달린 클래스가 비정적 중첩 테스트 클래스임을 나타냅니다. Java 8에서 Java 15까지의 경우 "클래스별" 테스트 인스턴스 수명 주기를 사용하지 않는 한 @BeforeAll 및 @AfterAll 메서드를 @Nested 테스트 클래스에서 직접 사용할 수 없습니다. Java 16부터 @BeforeAll 및 @AfterAll 메서드는 테스트 인스턴스 수명 주기 모드 중 하나를 사용하여 @Nested 테스트 클래스에서 static으로 선언될 수 있습니다. 이러한 주석은 상속되지 않습니다.
    @Tag
    클래스 또는 메서드 수준에서 테스트 필터링을 위한 태그를 선언하는 데 사용됩니다. TestNG의 테스트 그룹 또는 JUnit 4의 범주와 유사합니다. 이러한 주석은 클래스 수준에서 상속되지만 메서드 수준에서는 상속되지 않습니다.
    @Disabled
    테스트 클래스 또는 테스트 메서드를 비활성화하는 데 사용됩니다. JUnit 4의 @Ignore와 유사합니다. 이러한 주석은 상속되지 않습니다.
    @Timeout
    실행이 지정된 기간을 초과하는 경우 테스트, 테스트 팩터리, 테스트 템플릿 또는 수명 주기 메서드를 실패하는 데 사용됩니다. 이러한 주석은 상속됩니다.
    @ExtendWith
    확장을 선언적으로 등록하는 데 사용됩니다. 이러한 주석은 상속됩니다
    @RegisterExtension
    필드를 통해 프로그래밍 방식으로 확장을 등록하는 데 사용됩니다. 이러한 필드는 가려지지 않는 한 상속됩니다.
    @TempDir
    수명 주기 메서드 또는 테스트 메서드에서 필드 주입 또는 매개 변수 주입을 통해 임시 디렉터리를 제공하는 데 사용됩니다. org.junit.jupiter.api.io 패키지에 있습니다.

     

    1. @Tag

    테스트 코드들을 필터링하거나 그룹핑하는데 사용한다.

    @Tag는 테스트 메서드위에 직접 세팅하기도 하지만 별도의 어노테이션을 만들어 사용하기도 한다.

    @Tag명은 아래의 규칙에 따라 생성해야 한다.


    1. null이거나 비어 있지 않아야 합니다.
    2. 공백이 없어야 합니다.
    3. ISO 제어 문자가 포함되어서는 안 됩니다.
    4. 다음 예약 문자가 포함되어서는 안 됩니다.

    , : 콤마
    ( : 왼쪽 괄호
    ) : 오른쪽 괄호
    & : 앰퍼샌드
    | : 세로 막대
    ! : 느낌표

     

    ▶ 직접 세팅

    @DisplayName("출력되는_테스트_명을_입력한다.")
    @Tag("tagTest")
    @Test
    void test_display_name_under_scores() {
        log.info("test_display_name_under_scores");
        assertEquals("test","test");
    }

     

    ▶ annotation 생성

    같은 tag를 사용하는 테스트 메서들에 같은 새로 생성한 annotation을 추가하여 관리가능하다.

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import org.junit.jupiter.api.Tag;
    import org.junit.jupiter.api.Test;
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Tag("tagTest")
    @Test
    public @interface TagTest {
    }
    @DisplayName("출력되는_테스트_명을_입력한다.")
    @TagTest
    void test_display_name_under_scores() {
        log.info("test_display_name_under_scores");
        assertEquals("test","test");
    }

     

    ▶ 특정 tag들만 실행시키기 ( mac + Intellij 17.x.x ver )

    option을 class에서 Tags로 변경 후 @Tag("tag명")의 "tag명"을 입력하면 된다.

     

    상단 모듈 클릭 -> Edit Configurations 선택

    또는

    command + shift + A -> edit configuration 입력 후 엔터

     

    Junit config 추가 생성

     

    테스트를 위한 코드를 작성한다.

    아래코드엔 @Tag를 사용한 테스트 메서드

    @Tag를 사용하여 생성한 annotation인 @TagTest가 붙어있는 테스트 메서드

    그리고 @Tag가 붙어있지 않은 테스트 메서드가 있다.

     

    @Tag 메서드와 @TagTest는 같은 Tag명을 사용함으로 동시에 실행되어야한다.

    import static org.junit.jupiter.api.Assertions.*;
    
    import lombok.extern.slf4j.Slf4j;
    import org.junit.jupiter.api.AfterAll;
    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.DisplayNameGeneration;
    import org.junit.jupiter.api.DisplayNameGenerator;
    import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
    import org.junit.jupiter.api.Order;
    import org.junit.jupiter.api.Tag;
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.TestMethodOrder;
    import org.junit.jupiter.api.Timeout;
    
    @Slf4j
    @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
    @TestMethodOrder(OrderAnnotation.class)
    class JunitTest {
    
        @BeforeAll
        static void testBeforeAll() {
            log.info("BeforeAll");
        }
    
        @AfterAll
        static void testAfterAll() {
            log.info("AfterAll");
        }
    
        @DisplayName("출력되는 테스트 명을 입력한다.")
        @Order(1)
        @Timeout(1)
        @Test
        void testAnnotation() throws InterruptedException {
            log.info("testAnnotation");
            assertEquals("test","test");
            Thread.sleep(2000);
        }
    
        @Test
        @Tag("tagTest")
        @Order(3)
        void test_under_scores() {
            log.info("test_under_scores");
            assertEquals("test","test");
        }
    
        @DisplayName("출력되는_테스트_명을_입력한다.")
        @TagTest
        void test_display_name_under_scores() {
            log.info("test_display_name_under_scores");
            assertEquals("test","test");
        }
    }

    우측 상단에 새로 생성한 Junit config로 세팅 후 실행한다.

    실행 결과 의도한 테스트 메서드 두가지만 실행된걸 확인할 수 있다.

     

    ※ Tag 필터는 gradle, maven에서도 세팅 가능하다.

    gradle

    test {
        useJUnitPlatform {
            includeTags("tagTest", "추가 Tag명")
            // excludeTags("excludeTageName")
        }
    }

    maven

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M7</version>
                <configuration>
                    <groups>tagTest | 추가 tag명</groups>
                    <excludedGroups>excludeTagName</excludedGroups>
                </configuration>
            </plugin>
        </plugins>
    </build>

     

     

     

     

     

     

    Reference

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

    https://www.baeldung.com/junit-5

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

    댓글

Designed by Tistory.