일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 28 | 29 | 30 | 31 |
- 우아한세미나
- 스프링부트
- 미션
- 의존성
- 백준
- CircuitBreaker
- JUnit5
- 스프링 부트
- HTTP
- 프로그래머스
- 서블릿
- JPA
- 자바
- 우아한테크코스
- REDIS
- Level2
- Paging
- 트랜잭션
- Spring Batch
- AOP
- AWS
- Docker
- MSA
- mock
- 우테코
- 세션
- yml
- 코드리뷰
- 프리코스
- 레벨2
- Today
- Total
늘
JUnit5 사용하여 테스트 코드 작성하기 본문
테스트코드를 작성해보면서 JUnit4나 5를 사용하는데 이번 포스팅에서 4와 5를 비교하고 JUnit5 사용법에 초점을 맞춰서 정리해두려고한다.
Junit5
- Platform: Junit으로 작성한 테스트를 실행해주는 런처를 제공한다. TestEngineApi 제공한다.
- Vintage: Junit3과 4를 지원하는 TestEngine 구현체
- Jupiter: Junit5를 지원하는 TestEngineApI 구현체
Junit 5는 스프링부트 2.2 버전 이상부터는 기본적으로 의존성이 장착되어 따로 설정할 필요가 없다.
Junit5의 애노테이션들
@Test
- 테스트 메서드를 나타내주는 애노테이션이다.
- Junit4와 달리 어떠한 속성도 선언하지 않는다.
//Junit4
@Test(expected = Exception.class)
void test() throws Exception{
...
}
//Junit5
@Test
void test(){
...
}
@BeforeAll
- 해당 클래스에 위치한 모든 테스트 메서드 실행 전에 딱 한 번만 실행되는 메서드를 표시
- 해당 메서드는 static으로 선언해야한다.
@AfterAll
- 해당 클래스에 위치한 모든 테스트 메서드 실행 후에 딱 한 번만 실행되는 메서드를 표시
- 해당 메서드는 static으로 선언해야한다.
@BeforeEach
- 해당 클래스에 위치한 모든 테스트 메서드 실행 전에 실행되는 메서드를 표시
@AfterEach
- 해당 클래스에 위치한 모든 테스트 메서드 실행 후에 실행되는 메서드를 표시
각각 Junit4에 @BeforeClass/@AfterClass/@Before/@After와 유사하다.
BeforeAll vs BeforeEach
둘의 차이를 이해하기 힘들었는데 코드를 보면 이해하기 쉬울것 같다.
public class Test {
@BeforeAll
public static void beforeAll() {
System.out.println("@BeforeAll");
}
@BeforeEach
public void beforeEach() {
System.out.println("@BeforeEach");
}
@Test
public void test1(){
System.out.println("@Test 1");
}
@Test
public void test2(){
System.out.println("@Test 2");
}
@AfterEach
public void afterEach() {
System.out.println("@AfterEach");
}
@AfterAll
public static void afterAll() {
System.out.println("@AfterAll");
}
}
[결과]
@BeforeAll
@BeforeEach
@Test 1
@AfterEach
@BeforeEach
@Test 2
@AfterEach
@AfterAll
따라서, 테스트가 조건들에 의해 변경이 없다면 @BeforeAll, 변경이 있을 수도 있다면 @BeforeEach를 사용하면 좋다고 한다!
@Disabled
- 테스트 클래스나 테스트 메소드 를 사용하지 않는데 사용된다.
- Junit 4의 @Ignore 와 비슷하다.
[실행]
[결과]
@DisplayName
- 어떤 테스트인지 표시해주는 애노테이션
- 공백, 이모지, 특수문자까지 전부 지원해준다.
@RepeatedTest
- 특정 테스트를 반복 시키고 싶을때 사용하는 애노테이션
- 반복 횟수와 반복 테스트 이름을 설정 가능하다.
- 성능테스트를 할때 유용하다.
public class JunitTest {
@RepeatedTest(10)
@DisplayName("반복 테스트")
void repeatedTest() {
}
@RepeatedTest(value = 10, name = "{displayName} 중 {currentRepetition}")
@DisplayName("반복 테스트2")
void repeatedTest2(){
}
}
@ParameterizedTest
- 테스트에 여러 다른 매개변수들을 대입해가며 반복 실행할 때 사용하는 애노테이션
public class JunitTest {
@ParameterizedTest
@CsvSource(value = {"ACE, ACE:12", "ACE, ACE, ACE:13", "ACE,ACE,TEN:12"}, delimiter = ':')
void 에이스_카드가_여러_개일때_합_구하기(final String input, final int expected) {
final String[] inputs = input.split(",");
for(final String number : inputs){
final CardNumber cardNumber = CardNumber.valueOf(number);
dealer.receiveOneCard(new Card(cardNumber, CardType.CLOVER));
}
assertThat(dealer.calculateScore()).isEqualTo(expected);
}
}
delimiter를 기준으로 input과 expected로 값이 들어간다.
@Nested
- 테스트 클래스 안에서 내부 클래스를 정의해 테스트를 계층화 할 때 사용한다.
- @BeforeEach, @AfterEach와 같은 테스트 생명주기에 관계된 메서드들도 계층에 맞춰 동작한다.
@Assertions
- assertAll
- 매개변수로 받는 모든 테스트코드를 한번에 실행
- 오류가 나도 끝까지 실행한 뒤 한 번에 모아서 출력
-
public class JunitTest { @Test public void createProduct(){ Product product = new Product(); assertAll( () -> assertNotNull(product), () -> assertEquals(product.getMyprice(), 5000), () -> assertTrue(product.getLprice() < 1000, "1000원보다는 비싸야 한다.") ); } }
- assertThrows(expectedType, executable)
- 예외 발생을 확인하는 테스트
- executable의 로직이 실행하는 도중 expectedType의 에러를 발생시키는지 확인
-
public class JunitTest { @Test public void createProduct(){ Product product = new Product(); Exception e = assertThrows(Exception.class, () -> new Product(-100)); //예외가 던져지지 않음을 확인하는 assertDoesNotThrow assertDoesNotThrow(()-> System.out.println("do it")); } }
- assertTimeout(duration, executable)
- 특정 시간 안에 실행이 완료되는지 확인
- duration: 원하는 시간
- executable: 테스트할 로직
-
public class JunitTest { @Test @DisplayName("타임아웃 준수") void timeOutNotExceed(){ assertTimeout(ofMinutes(2), ()->Thread.sleep(10)); } @Test @DisplayName("타임아웃 초과") public void timeOut(){ assertTimeout(ofMillis(10), () -> Thread.sleep(100)); } }
레거시 Junt4 -> Junit5 변환
수작업으로 옮기는줄 알았는데 클릭으로만 가능한 방법이 있었다..!
이 외에 많은 기능들이 있었지만 자주 사용할법한 기능들을 위주로 정리했다.
테스트할때마다 자주 확인해야겠다.
Reference
- https://www.youtube.com/watch?v=EwI3E9Natcw&t=1s : 우아한Tech - 10분 테코톡
'백앤드 개발일지 > 스프링부트' 카테고리의 다른 글
[스프링부트] AOP를 이용한 로그파일 설정 & slf4j (0) | 2021.11.07 |
---|---|
[우아한 세미나]Spring-Boot-Admin & 외부 파일 위치 관리 (0) | 2021.10.04 |
서블릿 필터(Filter) vs 스프링 인터셉터(Intercepter) vs AOP (0) | 2021.09.19 |
[QureyDsl] 설정& 문법 & 오류 정리 (0) | 2021.09.02 |
[Spring Batch] 배치 애플리케이션 경험하기 2 (0) | 2021.08.31 |