슬기로운 개발생활

JUnit 5 소개

by coco3o
반응형

JUnit 5

JUnit 5는 런타임에 Java 8 버전 이상이 필요하다.

JUnit 5 모듈 구성

JUnit5는 이전버전과 달리 크게 3개의 서브 프로젝트로 구성된 복수의 모듈로 구성되어 있고,

각각의 프로젝트는 용도에 따라서 몇개의 서브 모듈로 구성되어 있다.

 

1. JUnit Platform

JUnit 테스트를 실행하기 위한 기반이 되는 모듈이다. Gradle, Maven과 같은 빌드툴은 물론 IDE를 위한 모듈도 각각 존재한다.

Platform이 제공하는 TestEngine 을 구현한 모듈을 찾아서 실행해준다.

 

2. JUnit Jupiter

테스트를 기술하기 위한 프로그램, 확장 모델들이 담겨있는 모듈이다.

흔히 JUnit5라고 언급할 경우 이 모듈을 지칭한다고 생각하면 될듯하다.

 

3. JUnit Vintage

JUnit의 3, 4 버전을 실행하기 위한 TestEngine 을 제공하는 모듈이다.

이 모듈을 통해서 JUnit 5와 병행 사용이 가능하다.

 

어노테이션(Annotation)

JUnit Jupiter는 테스트 구성 및 프레임 워크 확장을 위해 다음 주석을 지원한다.명시되지 않은 모든 핵심 주석은 모듈의 org.junit.jupiter.api 패키지에 있다.

주석 기술
@Test 테스트 방법임을 나타낸다. JUnit 4와 다르게 속성을 선언하지 않는다. JUnit Jupiter의 테스트 확장 프로그램은 자체 전용 주석을 기반으로 작동하기 때문이다. 이러한 메서드는 재정의 되지 않는 한 상속된다.
@ParameterizedTest 메서드는매개 변수화 된 테스트임을 나타낸다.이러한 메서드는 재정의 되지 않는 한 상속된다.
@RepeatedTest 반복 테스트를위한 테스트 템플릿임을 나타낸다.이러한 메서드는 재정의 되지 않는 한 상속된다.
@TestFactory 동적 테스트를위한 테스트 팩토리임을 나타낸다.이러한 메서드는 재정의 되지 않는 한 상속된다.
@TestTemplate 일반 테스트가 아닌 테스트 케이스의 템플릿임을나타낸다.이러한 메서드는 재정의 되지 않는 한 상속된다.
@TestMethodOrder 어노테이션이 있는 테스트 클래스에 대한테스트 메서드 실행 순서를 구성하는데 사용된다.
@TestInstance 어노테이션이 있는 테스트 클래스에 대한테스트 인스턴스 라이프 사이클을구성하는 데 사용된다. 이러한 주석은 상속 된다.
@DisplayName 테스트 클래스 또는 테스트 메서드의사용자 정의 표시 이름을선언한다. 이러한 주석은 상속되지 않는다.
@DisplayNameGeneration 테스트 클래스에 대한사용자 정의 표시 이름 생성기를선언한다. 이러한 주석은 상속 된다.
@BeforeEach @Test, @RepeatedTest, @ParameterizedTest, @TestFactory가 적힌 각 테스트 메서드 전에 실행된다.
@AfterEach @Test, @RepeatedTest, @ParameterizedTest, @TestFactory가 적힌 각 테스트 메서드 이후에 실행된다.
@BeforeAll @Test, @RepeatedTest, @ParameterizedTest, @TestFactory가 적힌 현재 클래스의 모든 테스트 메서드보다 먼저 실행된다.
해당메서드는 static이어야 한다.
@AfterAll @Test, @RepeatedTest, @ParameterizedTest, @TestFactory가 적힌 현재 클래스의 모든 테스트 메서드보다 이후에 실행된다.
해당메서드는 static이어야 한다.
@Nested 중첩 테스트 클래스임을 나타낸다. @BeforeAll 및 @AfterAll 방법은 직접 사용할 수 없다. @Nested는 "당 클래스"를 제외 테스트 클래스테스트 인스턴스 라이프 사이클이 사용된다.
@Tag 필터링 테스트를 위한 태그를 선언하는 데 사용한다. 이러한 주석은 클래스 레벨에서 상속 되지만 메서드 레벨에서는 상속 되지 않는다.
@Disabled 테스트 클래스 또는 테스트 방법을비활성화하는데 사용된다.
@Timeout 실행이 주어진 시간을 초과하는 경우 테스트 실패를 나타내기 위해 사용한다.
@ExtendWith 확장을 선언적으로 등록하는 데사용한다.
@RegisterExtension 필드를 통해프로그래밍 방식으로 확장을 등록하는데 사용된다.
@TempDir 수명주기 방법 또는 테스트 방법에서 필드 주입 또는 매개변수 주입을 통해임시 디렉토리를 제공하는데 사용한다.

Assertions

Assertion은 자신의 로직이 정확한지 테스트하는 것이다.

Jupiter에서는 기존 버전에 존재했던 Assertion 메서드를 포함하고, 람다와 함께 사용하기 적합한 추가적인 메서드를 제공한다.

모든 Assertion은 정적 메서드로 정의되어 있다.

@Test
void testCalculator() {
  //기본
  assertEquals(2, calculator.add(1,1));
  assertEquals(5, calculator.mul(2,5), "실패 메시지(optional)");
  
  //그룹
  assertAll(() -> assertEquals(3, calculator.sub(5,2)),
            () -> assertEquals(1, claculator.div(5,5)));
  
  //의존
  assertAll(() -> {
             assertAll(() -> assertTrue(),
                       () -> assertTrue());
           },
           () -> {
             assertAll(() -> assertEquals(),
                       () -> assertEquals());
           });
  
  //예외
  Exception e = assertThrows(ArithmeticException.class, () -> calculator.div(1, 0));
  assertEquals("/ by zero", e.getMessage());
  
  //제한시간
  assertTimeout(ofMinutes(2), () -> {
    // 2분 미만의 로직만 통과
  });
}

Assumptions

Assumption은 테스트를 진행할지 안할지에 대해 테스터가 작성한 가정을 기반으로 선택된다.
즉, 설정한 가정이 참일 경우에는 테스트를 실행하고 거짓일 겅우에는 테스트는 실행하지 않는다.
이러한 Assumption은 조그마한 단위 테스트보다는 통합 테스트에 더 적절히 사용할 수 있다.
Assertion과 똑같이 정적 메소드로 정의되어 있다.

@Test
void testOnlyOnDev() {
  assumeTrue("DEV".equals(System.getenv("ENV")));
  
  DEV 환경에서만 테스트할 코드;
}

@Test
void testAllEnv() {
  assumeTrue("DEV".equals(System.getenv("ENV")),
             () -> {
               DEV 환경에서 테스트할 코드;
             });

  모든 환경에서 테스트할 코드;
}

참고

반응형

블로그의 정보

슬기로운 개발생활

coco3o

활동하기