프로그래밍 공부/Java

[JUnit5] 테스트 기초 알아보기

우테코를 하며... 처음으로 말로만 들어보던 "TDD" 를 시작했다.

프리코스에서도 최대한 적용해보려고 했으나... 못했던 부분이기에 최대한 서치와 공부를 하며 기초적인 부분을 쌓았던 부분을 정리하고자 한다. 아직 앞으로 공부할게 잔뜩이다. 화이팅!!!! 

테..스트...코드...

 

 

1. JUnit5 5란?

테스트를 위한 프레임워크로, Java 8 이상의 버전에서 적용된다.

Junit 5의 전체적인 구조. 출처 (https://velog.io/@znftm97/JUnit5-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B01-33a88kr8)

  • JUnit5의 세부 모듈은 Jupiter, Vintage, JUnit Platform 으로 구성되어있다.
  • JUnit Platform
    • JVM에서 테스트 프레임워크를 실행하는데 기초를 제공한다.
    • TestEngine API를 제공해 테스트 프레임워크를 개발할 수 있다.
  • Jupiter & Vintage
    • Jupiter와 Vintage는 JUnit Platform이 제공하는 TestEngine API의 구현체이다.
    • Jupiter = JUnit5의 구현체
    • Vintage = 하위 호환성을 위한 JUnit3, JUnit4의 구현체

 

2. JUnit5 기본 Annoation

@Test : 해당 메서드가 테스트 메서드임을 명시할 때 사용

@Test
void test() {
    // ...
}

@DisplayName : 테스트 클래스나 테스트 메소드에 이름을 붙여줄 때 사용

@Test
@DisplayName("예비 테스트")
void test() {
    // ...
}

→ 테스트 메서드 명을 그냥 한글로 해도 되지 않나? 싶지만 아래 이미지와 같이 caution이 뜨기 때문에, DisplayName을 사용하는 것이 좋다.

이런식의 에러가 쌓이면 버그 fix가 힘들다!

 

@BeforeAll : 테스트가 시작하기전 딱 한번만 실행된다.

 

@BeforeEach : 각각 테스트 메서드가 실행되기 전에 실행되어야 하는 메서드를 명시해준다. `@Test` , @RepeatedTest , @ParameterizedTest , @TestFactory 가 붙은 테스트 메서드가 실행하기 전에 실행된다. JUnit4의 @Before와 같은 역할을 한다. 주로 테스트하기 전에 필요한 목업 데이터를 미리 세팅해주기 위해 주로 사용한다.

 

@AfterAll : 테스트가 완전히 끝난 후 딱 한번만 실행된다.

 

@AfterEach : @Test , @RepeatedTest , @ParameterizedTest , @TestFactory 가 붙은 테스트 메서드가 실행되고 난 후 실행된다. JUnit4의 @After 어노테이션과 같은 역할을 한다.

 

3. JUnit5 기본 Assertions and Assumptions

Assertions와 Assumptions가... 무슨 차이인지부터 알아보자.

뭔데... 뭐가다른데....

 

Assertions(단정문) : 만약 성공하지 않으면 테스트를 실패처리를 하기 위해서 사용.

Assumption(가정문) : 특정 상황에서만 test문을 실행하고자 할때, 반대로 특정 상황에서만 실행하지 않고자 할 때 사용하는 키워드. 여기서 말하는 특정 상황이라는 것은 local환경 등을 들 수 있다.

 

3.1. Assertions

모든 JUnit Jupiter assertion은 정적 메소드이며, org.junit.jupiter.api.Assertions 클래스 안에 있다.

다만, JUnitupiter가 제공해주는 assertion이 많은 테스트 시나리오에서 부족할 수 있다. 그럴 경우 JUnit 팀은 AssertJ , Hamcrest , Truth 등 써드 파티 라이브러리를 쓰는 걸 추천한다고 한다.

 

  • assertTrue, assertThat 등... Exception을 test 할 때는 assertThrows를 사용한다.
@Test
  void lambdaExpressions() {
      assertTrue(Stream.of(1, 2, 3)
        .stream()
        .mapToInt(i -> i)
        .sum() > 5, () -> "Sum should be greater than 5");
  }​
  • assertAll
 @Test
  void groupAssertions() {
      int[] numbers = {0, 1, 2, 3, 4};
      assertAll("numbers",
          () -> assertEquals(numbers[0], 1),
          () -> assertEquals(numbers[3], 3),
          () -> assertEquals(numbers[4], 1)
      );
  }

 

3.2. Assumptions

테스트와 직접적인 관련은 없으나, 일반적으로 테스트가 제대로 실행하기 위해 필요한 외부 조건에 사용된다.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.junit.jupiter.api.Assumptions.assumingThat;

public class AssumptionTest {
    private final Calculator calculator = new Calculator();

    @Test
    void CI서버에서만_테스트() {
        assumeTrue("CI".equals(System.getenv("ENV")));
    }

    @Test
    void 개발환경에서만_테스트() {
        assumeTrue("DEV".equals(System.getenv("ENV")),
                () -> "Aborting test: not on developer workstation");
    }

    @Test
    void 모든환경_테스트() {
        assumingThat("CI".equals(System.getenv("ENV")), () -> {
            // CI 서버에서만 실행하는 테스트
            assertEquals(2, calculator.divide(4, 2));
        });
        // 모든 환경에서 실행하는 테스트
        assertEquals(42, calculator.multiply(6, 7));
    }
}

 

 

참고자료

https://junit.org/junit5/docs/current/user-guide/ -> 공식문서!

https://withhamit.tistory.com/490

https://donghyeon.dev/junit/2021/04/11/JUnit5-%EC%99%84%EB%B2%BD-%EA%B0%80%EC%9D%B4%EB%93%9C/

https://gmlwjd9405.github.io/2019/11/26/junit5-guide-basic.html

'프로그래밍 공부 > Java' 카테고리의 다른 글

[JAVA] JVM이란?  (0) 2022.03.13
[Java] Stream API  (1) 2022.03.03
[OOP] 객체지향 프로그래밍  (0) 2022.03.02
[Regex] 정규식이란?  (2) 2022.02.21