자바 기본기 다시 정리하면서, 놓쳤던 부분을 정리하고자 합니다.
백기선 님의 자바 온라인스터디 4주차 내용입니다.
온라인스터디 과제 중 제가 학습에 필요한것들만 추려서 정리하였습니다.
(어떤 차이점이 있는지, 알아봅시다.)
-> 솔직히 JUnit5부터 사용하다보니.. 위의 문제점을 느끼지는 못했지만.. 이런것들 있었구나 정도는 알고 쓰도록 하자.
JUnit4은 모든 것이 하나의 Jar 파일로 묶여서 포함되어 있습니다.
JUnit5은 JUnit Platform, JUnit Jupiter, JUnit Vintage의 3가지 하위 프로젝트로 구성됩니다.
JUnit Platform : Platform에서 실행되는 새로운 테스트프레임워크를 개발하기 위한 TestEngine Api를 정의하고 있습니다.
JUnit Jupiter : 새로운 Annotation으로 작성된 테스트를 실행하기 위한 JUnit annotations와 TestEngine을 제공합니다.
JUnit Vintage : JUnit5 플랫폼에서 3,4버전으로 작성된 테스트코드를 실행할 수 있도록 지원합니다.
실제로 제가 사용하고 있는 라이브러리를 캡쳐해보았습니다. Platform, Jupiter 패키지가 존재하는 것을 확인할 수 있었습니다.
JUnit4: @Before, @After, @BeforeClass, @AfterClass, @Test
JUnit5: @BeforeEach, @AfterEach, @BeforeAll, @AfterAll, @Test
으로 바뀌었습니다.
위의 annotation들이 테스트 생명주기와 관련이 있으니 간단히 이야기해봅시다.
@BeforeAll : 현재 클래스의 모든 테스트 메서드 전에 1번 실행
@AfterAll : 현재 클래스의 모든 테스트 메서드 다 실행 후 1번실행
@BeforeEach : 각 테스트 메서드 전에 1번씩 실행
@AfterEach : 각 테스트 메서드 실행 후 1번씩 실행
#cf) 위의 특성을 사용해서 @Transcational 롤백을 사용하지 않고, 실제 H2-DB에 Test에 필요한 데이터들을 세팅하고, 테스트를 한 후 데이터를 지운적이 있다.
@Test
void testCalculator() {
//기본
assertEquals(2, calculator.add(1,1));
assertEquals(5, calculator.mul(2,5), "실패 메시지(optional)");
//그룹
assertAll(() -> assertEquals(3, calculator.sub(5,2)),
() -> assertEquals(1, claculator.div(5,5)));
//의존
assertAll(() -> {
assertAll(() -> assertTrue(),
() -> assertTrue());
},
() -> {
assertAll(() -> assertEquals(),
() -> assertEquals());
});
//예외
Exception e = assertThrows(ArithmeticException.class, () -> calculator.div(1, 0));
assertEquals("/ by zero", e.getMessage());
//제한시간
assertTimeout(ofMinutes(2), () -> {
// 2분 미만의 로직만 통과
});
}
기존에 우리가 작성하는 코드들은 정적 테스트 코드이다.
ex)
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 4, 5})
void isUnderTenTest(int number) {
boolean result = isUnderTen(number);
assertThat(result).isTrue();
}
동적테스트 코드는 Runtime에 생성되는 테스트를 수행한다는 것이다. 차이가 잘 와닿지 않는다.
코드를 보자
@TestFactory
Stream<DynamicTest> isUnderTenTest() {
List<Integer> numbers = getNumberFromDatabase(); // 1, 2, 3, 4, 5, 6, 7, 8, 9
return numbers.stream()
.map(num -> dynamicTest(num + "가 10미만인지 검사",
() -> {
boolean result = num < 10;
assertThat(result).isTrue();
}
));
}
어떤게 가장 큰 차이일까? 다이나믹 테스트의 강력함은 테스트 케이스가 동적으로 생성되고 수행되기 때문에, 여러 dynamicTest안에서 데이터 결과를 공유하고 연속성 있는 테스트를 작성할 수 있다는 점이다.
또한 통합테스트를 할 때, 테스드들을 묶고, 데이터를 공유하면서 작성할 때 좋은 방법으로 사용될 수 있어보인다.
JUnit5: 특정 조건에서만 테스트를 실행할 수 있도록 @EnabledIf, @DisabledIf 등의 애노테이션을 제공합니다.
필자는 맥북을 사용하는데 테스트가 ignored 되는 것을 볼 수 있엇다.
https://junit.org/junit5/docs/current/user-guide/#overview
https://howtodoinjava.com/junit5/junit-5-vs-junit-4/
https://tecoble.techcourse.co.kr/post/2020-07-31-dynamic-test/