Spring Boot Test - Junit5 어노테이션
💡 Spring Test 어노테이션
테스트에서 Spring Bean 사용하기
@SpringBootTest
Spring Application Context를 사용하는 테스트
org.springframework.boot.test.context.SpringBootTest
@DataJpaTest
Spring Application에서 JPA 관련 bean만 사용하는 테스트
org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
@Import
Bean 을 불러와 사용할 수 있도록 해줌
org.springframework.context.annotation.Import
@TestConfiguration
특정 테스트에서 사용할 bean을 정의하는 설정 파일 작성시 사용
이 어노테이션으로 구성 파일을 작성 한 경우
사용 할 테스트 클래스에서 @Import 어노테이션을 통해 읽어와야 한다.org.springframework.boot.test.context.TestConfiguration
📜 JUnit 5 어노테이션
@Test
- 기본 실행 어노테이션
- Test 어노테이션이 붙은 메서드만 테스트 실행 가능
1
2
3
4
5
6
class ApplicationTest {
@Test
void test() {
// ..
}
}
@RepeatableTest
- 반복 실행 어노테이션
- 이 것 역시 Test 어노테이션이므로 메서드에 붙이면 테스트로 실행 된다.
- 이 어노테이션을 붙인 메서드는 지정한 횟수만큼 반복 실행된다.
- 횟수는 어노테이션에 int값으로 지정
- name 값을 입력해 줄 수도 있는데, name 값에 사용할 수 있는 Placeholder가 몇 가지 제공된다.
{currentRepetition}
: 현재 수행 된 횟수{totalRepetition}
: 수행 될 총 실행 횟수
1
2
3
4
5
6
7
8
9
10
11
class ApplicationTest {
private int count = 0;
@RepeatedTest(
value = 5,
name = "{currentRepetition} of {totalRepetition}"
)
void test() {
System.out.printf("📍 test 실행 %d회", ++count);
}
}
@ParameterizedTest
- 매개변수를 제공해야 하는 테스트 메서드에 붙이는 어노테이션
- 이 것 역시 Test 어노테이션이므로 메서드에 붙이면 테스트로 실행 된다.
- @ValueSource와 같은
Source 어노테이션과 함께 사용
한다. - name 값을 입력해 줄 수도 있는데, name 값에 사용할 수 있는 Placeholder가 몇 가지 제공된다.
{index}
: 현재 실행 횟수 (1부터 시작){arguments}
: 매개변수 이름{argumentsWithNames}
: “매개변수 이름=값”{0}
: 지정한 위치의 매개변수 값 (왼쪽부터 0번)- ex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
class ApplicationTest { @ParameterizedTest( name = "테스트 {index} , {arguments} , {argumentsWithNames} , null : {0}" ) @ValueSource(strings = { "email", "nickname", "password", "role" }) void test(String nullField) { /* 테스트 실행 시 출력되는 display name 값 테스트 1 , nullField , nullField=email , null : email 테스트 2 , nullField , nullField=nickname , null : nickname 테스트 3 , nullField , nullField=password , null : password 테스트 4 , nullField , nullField=role , null : role */ } }
- ParameterizedTest와 함께 어떤 형태로 parameter를 전달할지 알려주는 Source 어노테이션을 함께 사용한다.
주요 Source 어노테이션
@ValueSource(type = {})
- type으로 기본 자료형 배열, String 배열, Class 배열을 사용할 수 있다.
- 한 가지 타입만 사용 가능
- ex 1. string 타입
1 2 3 4 5 6 7 8 9
class ApplicationTest { @ParameterizedTest @ValueSource(strings = { "a", "b", "c", "d" }) void test(String name) { // .. } }
- ex 2. int 타입
1 2 3 4 5 6 7 8 9
class ApplicationTest { @ParameterizedTest @ValueSource(ints = { 1, 2, 3, 4 }) void test(int name) { // .. } }
- ex 3. Class
1 2 3 4 5 6 7 8 9 10 11
class ApplicationTest { @ParameterizedTest @ValueSource(classes = { RuntimeException.class, ApiException.class, UsernameNotFoundException.class }) void test(Class<? extends Exception> exception) { // .. } }
@CsvSource({ “”, “”, .. , “” })
- csv 스타일로 매개변수 집합을 간단하게 정의할 수 있다.
- 매개변수를 여러개 필요로 하는 경우에 사용
- 기본 타입 자료형만 사용할 수 있으며 여러 타입을 함께 전달 가능
- 문자열은
' '
(작은 따옴표)로 감싸서 입력
- 문자열은
- ex
1 2 3 4 5 6 7 8 9 10 11 12
class ApplicationTest { @ParameterizedTest @CsvSource({ "'홍길동', 1, 3.3, c", "'홍길서', 2, 4.4, d", "'홍길남', 3, 5.5, e", "'홍길북', 4, 6.6, f" }) void test(String name, int index, double point, char alpha) { // .. } }
@MethodSource(value = Strings[])
- 매개 변수를 정의한 메서드를 value에 명시하면 테스트 실행시 값이 전달된다.
- value = {“메서드 이름 1”, “메서드 이름 2”}
- value 생략 가능 입력하지 않으면 해당 테스트 메서드와 같은 이름을 찾아 사용한다.
- 매개변수를 정의하는 메서드는
- static 타입으로 작성
- 매개변수를 여러개 전달할 경우 Arguments 배열 반환
- ex 1. value 입력 x - 같은 메서드 이름 사용
1 2 3 4 5 6 7 8 9 10 11 12
class ApplicationTest { @ParameterizedTest @MethodSource void test(String name) { // .. } static Stream<String> test() { return Stream.of( "a", "b", "c", "d" ); } }
- ex 2. value 입력 - 다른 메서드 이름 사용
1 2 3 4 5 6 7 8 9 10 11 12
class ApplicationTest { @ParameterizedTest @MethodSource("test_parameter_type_string") void test(String name) { // .. } static Stream<String> test_parameter_type_string() { return Stream.of( "a", "b", "c", "d" ); } }
- ex 3. 매개변수 여러 개 전달
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class ApplicationTest { @ParameterizedTest @MethodSource void test(String name) { // .. } static Stream<Arguments> test() { return Stream.of( Arguments.of(1, "a"), Arguments.of(2, "b"), Arguments.of(3, "c"), Arguments.of(4, "d") ); } }
- 매개 변수를 정의한 메서드를 value에 명시하면 테스트 실행시 값이 전달된다.
@NullAndEmptySource
- 매개변수에 Null 과 Empty 값을 넣어준다.
1 2 3 4 5 6 7 8
class ApplicationTest { @ParameterizedTest @ValueSource(strings = {"a", "b", "c", "d"}) @NullAndEmptySource void test(String name) { // .. } }
- 매개변수에 Null 과 Empty 값을 넣어준다.
- @CsvFileSource
- csv 형식의 파일을 불러와서 사용
- @EnumSource
- enum 데이터를 사용
- @ArgumentsSource
- @NullSource
- null 주입
- @EmptySource
- 빈 값 주입
@DisplayName
테스트 클래스나, 테스트 메서드에 이름을 직접 지정할 때 사용한다.
이 어노테이션을 사용하지 않으면 테스트 실행 결과 목록에 클래스명이나 메서드명이 나타남
@DisplayNameGeneration
테스트 클래스에 이 어노테이션을 붙이면, 테스트 보고서에 표시될 테스트 메서드 이름 / 클래스 이름을 변경할 수 있다.
어노테이션 인자로 DisplayNameGenerator 구현체를 전달해야 한다.
기본 제공 구현체
Simple
: 기본값으로, 테스트 메서드 이름을 그대로 사용ReplaceUnderscores
: 테스트 메서드 이름에서 밑줄(_)을 공백으로 치환IndicativeSentences
: 테스트 클래스와 메서드 이름을 사용하여 문장 형성
이외에도 DisplayNameGenerator 인터페이스를 구현한 클래스를 작성하여, 사용자 정의 규칙을 생성하여 사용 할 수도 있다.
@BeforeEach
각 테스트 메서드가 실행되기 전에 호출되는 메서드에 이 어노테이션을 사용한다.
@BeforeAll
테스트 클래스의 모든 테스트 메서드가 실행되기 전에 한 번만 호출되는 메서드에 이 어노테이션을 사용한다. 테스트는 기본적으로 메서드 단위로 인스턴스를 실행하기 때문에, 이 메서드는 static
이어야만 한다.
@AfterEach
각 테스트 메서드가 실행된 후에 호출되는 메서드에 이 어노테이션을 사용한다.
@AfterAll
테스트는 기본적으로 메서드 단위로 인스턴스를 실행하기 때문에, 이 메서드는 static
이어야만 한다.
@Disabled
테스트 메서드나 테스트 클래스를 비활성화하는 데 사용되는 어노테이션.
이 어노테이션이 붙은 테스트는 실행되지 않는다.
@Nested
중첩된 테스트 클래스를 나타내는 데 사용되는 어노테이션.
이 어노테이션을 사용하면 관련된 테스트를 그룹화하여 더 명확한 구조를 만들 수 있다.
@Tag
테스트 메서드나 클래스에 태그를 붙이는 데 사용되는 어노테이션이다.
태그를 사용하면 특정 테스트 그룹을 선택하여 실행할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Tag("includeTag")
public class TagTest {
@Test
void aTest() {
System.out.println("a include ==========================");
}
@Test
void bTest() {
System.out.println("b include ==========================");
}
}
@Tag("notInclude")
class TacTest {
@Test
void aTest() {
System.out.println("not include a ==========================");
}
@Test
void bTest() {
System.out.println("not include b ==========================");
}
}
Tag 사용을 위한 build.gradle 설정
1
2
3
4
5
6
test {
useJUnitPlatform {
includeTags("includeTag")
excludeTags("notIncludeTag")
}
}
Junit 5 Documents