테스트를 위한 프레임워크로 Junit5는 3가지 모듈로 구성
- 자바8 이상부터 사용이 가능
- 스프링부트 2.2버전 이상부터는 기본적으로 Junit5가 의존성으로 추가된다.
[ 구조 ]

출처) https://velog.io/@znftm97/JUnit5-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B01-33a88kr8
[1] @Test
테스트 메서드에 사용
[1] @BeforeAll / @AfterAll
해당 클래스에 존재하는 모든 테스트 메서드 실행 전/후 딱 한 번 실행
💡 어떤 조건이 테스트에 영향을 미치지 않다는 확신이 있을 때 사용
💡 리턴 타입과 private 키워드가 존재하면 안된다. (void와 static을 기본으로 사용하자)
[2] @BeforeEach / @AfterEach
해당 클래스에 위치한 모든 테스트 메서드 실행 전/후 실행
💡 주로 @BeforeEach는 초기 데이터를 세팅하기 위해서도 사용
💡 어떤 조건이 테스트에 영향을 준다고 할 때 사용해 테스트마다 새로운 클래스 생성
💡 @Test, @RepeatedTest, @ParameterizedTest, @TestFactory가 붙은 메서드를 실행 전 먼저 실행
[3] @Disabled
테스트를 하지 않을 메서드나 클래스에 사용
💡 주석과 같은 기능
[4] @DisplayName / @DisplayNameGeneration
각 테스트 클래스나 메서드에 이름(설명)을 부여
💡 테스트 실행 시 콘솔 창에 이 설명을 볼 수 있다.
💡 @DisplayName가 우선순위가 높다.
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
[5] @RepeatedTest
특정 테스트를 여러 번 반복
💡 value 속성으로 반복 횟수와 name 속성으로 테스트 이름을 설정 가능
💡 성능이슈 확인 가능@RepeatedTest(value = 반복 횟수, name = "반복 테스트명")
💡 name 속성
💡 매개변수 타입
[1] TestInfo 타입
[2] RepetitionInfo 타입
💡 예시
@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 속성
💡 인자 제공을 위한 source 어노테이션
💡 예시
@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
테스트, 메소드 테스트를 구분하기 위해 사용
💡 커스텀 태그
: 직접 태그를 만들고 여러 번 사용하면 코드의 중복과 에러를 줄일 수 있다.
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
특정 환경변수에 따라 테스트를 실행하고자 할 때 사용