프로그래밍/JUnit

[JUnit5 개요] Meta 애노테이션과 Assumption, test 실행 순서에 대해

Jay22 2019. 5. 9. 16:11
반응형

JUnit5 개요

JUnit5 User Guide

Junit 공식 문서를 보며 정리해 보았다. 각 챕터 번호는 해당 공식 문서에 매칭되는 번호이다.

https://junit.org/junit5/docs/current/user-guide/#overview-what-is-junit-5

1.1 JUnit5란 무엇인가

JUnit5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

JUnit Platform : JVM에서 돌아가는 테스트 프레임워크이다. 테스트 엔진 API 으로도 정의되며 더욱이 Gradle과 Maven, JUnit4의 빌드 플러그인을 만들 수 있고 커맨드 라인에서 돌아가는 콘솔 런쳐를 제공한다.

JUnit Jupiter : JUnit5에서의 테스트 작성을 위한 새로운 프로그래밍 모델, 확장모델 이다.

JUnit Vintage : JUnit3 와 JUnit4를 가능하게 해주는 테스트 엔진이다.

지원하는 Java 버젼

JUnit5 는 런타임때 Java8버전(혹은 그 이상)이 필요하다. 하지만 이전 버전 JDK에서 컴파일된 코드들은 테스트 가능하다.

2.1.1 Meta-Annotations

메타 애노테이션이란?

@Target

어느 부분에 애노테이션을 사용할지 결정한다.

  • CONSTRUCTOR: 생성자 선언시
  • FIELD: 필드값 선언시
  • LOCAL_VARIABLE: 지역 변수 선언시
  • METHOD: 메서드 선언시
  • PACKAGE: 패키지 선언시
  • PARAMETER: 매개 변수 선언시
  • TYPE: 클래스, 인터페이스, enum 선언시

@Retention

언제 까지 애노테이션이 유지가 되는지 결정한다.

  • SOURCE: 애노테이션이 컴파일시 사라짐
  • CLASS: 클래스 파일에 있는 애노테이션 정보가 컴파일러에 의해 참조 가능. 가상머신에서 사라짐
  • RUNTIME: 실행시 애노테이션 정보가 가상 머신에 의해 참조 가능.

@Documentation

해당 애노테이션에 대한 정보가 문서에 포함된 다는 것을 선언한다.

@Inherited

모든 자식 클래스가 부모 클래스의 애노테이션을 사용할 수 있다는 것을 선언한다.

메타 애노테이션 정보 참조: https://secretroute.tistory.com/entry/%EC%9E%90%EB%B0%94%EC%9D%98%E7%A5%9E-Vol1-Annotation

2.15 Parameterized Tests

@ParameterizedTest는 @Test와 비슷하지만 여러 인자들을 한 번에 테스트해볼 수 있다. 홈페이지에서 제공하는 예제이다.

@ParameterizedTest
@ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })
void palindromes(String candidate) {
    assertTrue(StringUtils.isPalindrome(candidate));
}

회문을 검사하는 예제인데 각 string들을 차례로 테스트해볼 수 있다.

Test Classes and Methods

라이프 사이클

@BeforeAll

각 테스트 전에 실행 된다. 즉 테스트 하나 당 한 번씩 실행되는 것이다. JUnit4의 @Before와 같다.

@AfterEach

각 테스트 이후에 실행 된다. JUnit4의 After와 같다.

@BeforeAll

모든 테스트 전에 딱 한 번 실행 된다. JUnit4의 @BeforeClass와 같다.

@AfterAll

모든 테스트 이후에 딱 한 번 실행 된다. JUnit4의 @AfterClass와 같다.

2.3 Display Names

IntelliJ기준 왼쪽 하단에 테스트들이 실행될 때 각 테스트들이 어떤 이름으로 보여질지를 설정할 수 있다. 함수 이름으로 한국어를 쓸 수 있으므로 그닥 중요해보이진 않지만, 심지어 특수문자나 emoji 까지 지원하는게 신기해서 넣어보았다...

@Test
    @DisplayName("╯°□°)╯")
    void testWithDisplayNameContainingSpecialCharacters() {
    }

2.5 Assumptions

이 챕터는 JUnit5에서 개선한 파트이다. 꽤나 유용하다.

직역하면 가정이란 뜻인데 특정 환경에 있을 때만 테스트를 실행할 수 있다. 예를들어, 테스트를 특정 운영체제에서만 실행하거나 특정 개발환경 (테스트, 개발환경 등)에서만 실행하고 싶을 때 유용하게 쓸 수 있다.

다음은 공식 문서의 예제 코드이다.

class AssumptionsDemo {

    private final Calculator calculator = new Calculator();

    @Test
    void testOnlyOnCiServer() {
        assumeTrue("CI".equals(System.getenv("ENV")));
        // remainder of test
    }

    @Test
    void testOnlyOnDeveloperWorkstation() {
        assumeTrue("DEV".equals(System.getenv("ENV")),
            () -> "Aborting test: not on developer workstation");
        // remainder of test
    }

    @Test
    void testInAllEnvironments() {
        assumingThat("CI".equals(System.getenv("ENV")),
            () -> {
                // perform these assertions only on the CI server
                assertEquals(2, calculator.divide(4, 2));
            });

        // perform these assertions in all environments
        assertEquals(42, calculator.multiply(6, 7));
    }

}

첫 번째 테스트 메서드를 보자. System에서 환경변수를 가져온다. 그것이 CI 서버 환경이라면 테스트가 실행된다. 주석 부분에 테스트를 작성하면 된다. 여기서 중요한 점은 CI 서버 환경이 아니라면 테스트가 실패하는 것이 아니라 테스트가 스킵되는 것이다.

혹은 두 번째 메서드처럼 람다식으로 쓸 수 있다. 혹은 세 번째 메서드처럼 that구문을 활용하여 조금 더 자연스럽게 읽히도록 작성할 수 있다.

2.9 Test Execution Order

클래스 내에 테스트의 진행 순서를 결정할 수 있다. 각 단위 테스트는 서로 의존하게 끔 하면 안되기 때문에 순서는 상관없지만 가독성을 위해 쓸 수 있다.

@TestMethodOrder(OrderAnnotation.class)
class OrderedTestsDemo {
    @Test
    @Order(1)
    void nullValues() {
        // perform assertions against null values
    }

    @Test
    @Order(2)
    void emptyValues() {
        // perform assertions against empty values
    }

    @Test
    @Order(3)
    void validValues() {
        // perform assertions against valid values
    }
}

@TestMethodOrder 라는 애노테이션을 사용하면 되는데 3가지 설정을 할 수 있다.

  • Alphanumeric: 알파벳 순으로 실행
  • OrderAnnotation: Order 애노테이션으로 지정한 순서대로 실행
  • Random: 랜덤 실행
반응형