[SpringBoot] Junit5 사용법(1)

이수정·2023년 1월 11일

1. Junit5이란?

테스트를 위한 프레임워크로 Junit5는 3가지 모듈로 구성

  • 자바8 이상부터 사용이 가능
  • 스프링부트 2.2버전 이상부터는 기본적으로 Junit5가 의존성으로 추가된다.

[ 구조 ]

출처) https://velog.io/@znftm97/JUnit5-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B01-33a88kr8

  • Junit Platform
    • JVM에서 테스트 프레임워크를 실행하는데 기초 제공
    • TestEngine API 제공
  • Jupiter / Vintage
    • 둘 다 Junit Platform이 제공하는 TestEngine의 구현체
      • Jupiter는 Junit5의 구현체
      • Vintage는 하위 호환을 위한 Junit3과 Junit4의 구현체





2. Junit5 어노테이션

[1] @Test

테스트 메서드에 사용


[1] @BeforeAll / @AfterAll

해당 클래스에 존재하는 모든 테스트 메서드 실행 전/후 딱 한 번 실행
💡 어떤 조건이 테스트에 영향을 미치지 않다는 확신이 있을 때 사용
💡 리턴 타입과 private 키워드가 존재하면 안된다. (void와 static을 기본으로 사용하자)


[2] @BeforeEach / @AfterEach

해당 클래스에 위치한 모든 테스트 메서드 실행 전/후 실행
💡 주로 @BeforeEach는 초기 데이터를 세팅하기 위해서도 사용
💡 어떤 조건이 테스트에 영향을 준다고 할 때 사용해 테스트마다 새로운 클래스 생성
💡 @Test, @RepeatedTest, @ParameterizedTest, @TestFactory가 붙은 메서드를 실행 전 먼저 실행


[3] @Disabled

테스트를 하지 않을 메서드나 클래스에 사용
💡 주석과 같은 기능


[4] @DisplayName / @DisplayNameGeneration

각 테스트 클래스나 메서드에 이름(설명)을 부여
💡 테스트 실행 시 콘솔 창에 이 설명을 볼 수 있다.
💡 @DisplayName가 우선순위가 높다.

  • @DisplayName: 사용자가 직접 정의
  • @DisplayNameGeneration: 예) @Test 메소드 이름에 _로 표시한 부분 모두 space로 처리
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)


[5] @RepeatedTest

특정 테스트를 여러 번 반복
💡 value 속성으로 반복 횟수와 name 속성으로 테스트 이름을 설정 가능
💡 성능이슈 확인 가능

@RepeatedTest(value = 반복 횟수, name = "반복 테스트명")

💡 name 속성

  • {displayName}: @DisplayName으로 설정한 이름 값
  • {currentRepetition}
  • {totalRepetitions}

💡 매개변수 타입

[1] TestInfo 타입

  • getDisplayName()
  • getTags()
  • getTestMethod()
  • getTestClass()

[2] RepetitionInfo 타입

  • getCurrentRepetition()
  • getTotalRepetitions()
  • SHORT_DISPLAY_NAME
  • LONG_DISPLAY_NAME
  • DISPLAY_NAME_PLACEHOLDER
  • TOTAL_REPETITIONS_PLACEHOLDER
  • CURRENT_REPETITION_PLACEHOLDER

💡 예시

@RepeatedTest(value = 1, name = "{displayName} {currentRepetition}/{totalRepetitions}")
@DisplayName("RepeatTest,")
void repeatedTestWithDisplayName (TestInfo testInfo) {
    assertEquals("RepeatTest, 1/1", testInfo.getDisplayName())
}
@RepeatedTest(value = 1, name = RepeatedTest.LONG_DISPLAY_NAME)
@DisplayName("repeatedTest")
void repeatedTestWithLONGDISPLAYNAME(TestInfo testInfo) {
    assertEquals("repeatedTest :: repetition 1 of 1", testInfo.getDisplayName());
}
@RepeatedTest(10)
void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
    assertEquals(10, repetitionInfo.getTotalRepetitions());
}


[6] @ParameterizedTest

한 테스트에 여러 매개변수을 대입하며 반복 실행

💡 name 속성

  • {displayName}
  • {index}: 현재 반복 횟수
  • {0}, {1}, {2}, ...: 매개변수에 해당하는 값

💡 인자 제공을 위한 source 어노테이션

  • @ValueSource: 한 종류 인자만 제공
  • @NullSource: null 제공, 다른 어노테이션과 함께 사용
  • @EmptySource: 빈 값(문자열, 배열) 제공, 다른 어노테이션과 함께 사용
  • @NullAndEmptySource
  • @CsvSource: 리스트를 콤마(,)로 구분해 제공
  • @EnumSource

💡 예시

@ParameterizedTest 
@ValueSource(ints = { 1, 2, 3 }) 
void testWithValueSource(int argument) {
	assertTrue(argument > 0 && argument < 5); 
}
@ParameterizedTest 
@NullSource 
@EmptySource 
@ValueSource(strings = { " ", " ", "\t", "\n" }) 
void nullEmptyAndBlankStrings(String text) {
  assertTrue(text == null || text.trim().isEmpty()); 
}
@ParameterizedTest
@CsvSource({
  "orange, 1",
  "yellow, 2",
  "'green, blue', 0xF1" 
})
void testWithCsvSource(String color, int count) {
  assertNotNull(color);
  assertNotEquals(0, count); 
}


[7] @Nested

테스트 클래스안에서 내부 클래스(Inner class)를 정의해 테스트를 계층화
💡 내부 클래스는 부모 클래스 필드에 접근 가능
💡 라이프사이클이 per-class로 설정되어 있지 않다면 @BeforeAll, @AfterAll 동작 안함


[8] @Timeout

특정 시간 안에 테스트가 실행되는지 확인

@Timeout(value =, unit = 시간단위)


[9] @Tag

테스트, 메소드 테스트를 구분하기 위해 사용

  • Intellij에서 Edit -> Run/Debug Configuration -> Test kind -> Tags로 변경 -> Tag expression에 실행을 원하는 Tag를 입력 -> 이 Tag를 가진 테스트만 실행

💡 커스텀 태그

: 직접 태그를 만들고 여러 번 사용하면 코드의 중복과 에러를 줄일 수 있다.

1) 커스텀 태그 작성

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Tag("값")
@Test
public @interface 태그이름 {
}

2) 커스텀 태그 사용

@태그이름
@DisplayName("tag test)
void tagWithCustomTag() {
    System.out.println("커스텀 태그 테스트");
}


[10] @TestFactory

테스트를 동적으로 수행


[11] @TestInstance

테스트 인스턴스의 라이프 사이클을 설정


[12] @TestTemplate

Provider에 의해 여러 번 호출될 수 있는 테스트 케이스 템플릿인 것을 표현


[13] @TestMethodOrder

테스트 메서드의 실행 순서를 구성하는데 사용


[14] @ExtendWith

확장을 선언적으로 등록할 때 사용, 이 어노테이션은 확장 가능


[15] @RegisterExtension

필드를 통해 프로그래밍 방식으로 확장을 등록할 때 사용


[16] @TempDir

필드 주입이나 매개변수 주입으로 임시 디렉터리를 제공


[17] @EnabledOnOs

특정 OS에서만 동작하도록 할 때 사용


[18] @EnabledIfEnvironmentVariable / @DisabledIfEnvironmentVariable

특정 환경변수에 따라 테스트를 실행하고자 할 때 사용

profile
개발 공부 기록

0개의 댓글