JUnit 5가 출시된 후, 많은 개발자들은 이惊人的 새로운 라이브러리를 프로젝트에 추가했습니다. 다른 버전과 달리, 이 새로운 버전에서는 JUnit 4에서 5로 이관할 필요가 없으며, 프로젝트에 새로운 라이브러리를 포함시키기만 하면 됩니다. 그런 다음 JUnit 5 엔진을 사용하여 새로운 테스트를 수행하고, 기존의 JUnit 4나 3 테스트는 문제없이 계속 실행됩니다.
하지만 10년 전에 만들어진 대형 프로젝트에서, JUnit의 두 버전이 병렬로 실행되는 프로젝트에서는 어떤 일이 벌어질 수 있을까요?
새로운 개발자들이 프로젝트에 참여하기 시작했는데, 그 중 일부는 JUnit 경험이 있고, 다른 일부는 그렇지 않습니다. 새로운 테스트는 JUnit 5와 JUnit 4를 사용하여 만들어지고, 언제든지 경험이 없는 개발자가 새로운 시나리오를 JUnit 5 테스트에 추가할 때, 그들은 단순히 JUnit 4 애너테이션을 포함시키고 테스트가 JUnit 4와 JUnit 5의 @Test
가 혼합된 것으로 변합니다. 그리고 하루가 지날수록 JUnit 4 라이브러리를 제거하기가 점점 더 어려워집니다.
그런 문제를 어떻게 해결할까요? 우선, 팀에게 JUnit 5와 JUnit 4의 차이를 보여주어야 합니다. 그래야 새로운 테스트가 JUnit 4 대신 JUnit 5를 사용하여 만들어질 수 있습니다. 그런 다음, 보이스카웃 규칙을 따르는 것이 중요합니다. JUnit 4 테스트를 통과할 때마다 JUnit 5로 이관해야 합니다.
JUnit 5에서 주요 변경 사항을 살펴보겠습니다. 이름에서부터 시작하겠습니다, JUnit 5에서는 org.junit5라는 패키지 대신 org.junit.jupiter를 사용합니다. 간단히 말해 “Jupiter”로 시작하는 모든 것은 JUnit 5에서 온 것을 의미합니다. 이 이름은 Jupiter가 “JU”로 시작하며 태양에서 다섯 번째 행성이라는 이유로 선택되었습니다.
다른 변화는 @Test
어노테이션에 대한 것입니다. 이 어노테이션은 새로운 패키지로 이동되었습니다: org.junit.jupiter.api이며, 이제 “expected”나 “timeout”과 같은 속성을 더 이상 사용하지 않고 대신 확장을 사용합니다. 예를 들어, 타임아웃에 대해선 이제 다음과 같은 어노테이션을 사용합니다: @Timeout(value = 100, unit = TimeUnit.MILLISECONDS)
. 또 다른 변화는 테스트 메서드나 클래스가 public으로 선언되지 않아도 됩니다.
이제 테스트 구성에서 @Before
와 @After
를 사용하는 대신 @BeforeEach
와 @AfterEach
를 사용해야 하며, 또한 @BeforeAll
와 @AfterAll
도 있습니다.
테스트를 무시하려면 이제 @Ignore
대신 @Disable
를 사용해야 합니다.
A great news that was released in JUnit 5 was the annotation @ParameterizedTest
, with that is possible to run one test multiple times with different arguments. For example, if you want to test a method that creates some object and you want to validate if the fields are filled correctly, you just do the following:
@ParameterizedTest
@MethodSource("getInvalidSources")
void shouldCheckInvalidFields(String name, String job, String expectedMessage) {
Throwable exception = catchThrowable(() -> new Client(name, job));
assertThat(exception).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(expectedMessage);
}
static Stream<Arguments> getInvalidSources() {
return Stream.of(Arguments.arguments("Jean Donato", "", "Job is empty"),
Arguments.arguments("", "Dev", "Name is empty"));
}
JUnit 5에는 많은 좋은 기능들이 있으므로 JUnit 5의 사용자 가이드를 확인하여 프로젝트에 유용한 것을 분석해보시기 바랍니다.
지금이 JUnit 5에서 변경된 내용을 모든 개발자들이 알고 있는 상태에서, 프로젝트에서 JUnit 4를 제거하는 과정을 시작할 수 있습니다. 따라서, 2024년에도 여전히 JUnit 4를 사용하고 있고, 프로젝트가 큰 프로젝트라면, 프로젝트에 JUnit 4를 사용하는 어떤 종속성이 있을 가능성이 높습니다. 여러분의 라이브러리를 분석하여 JUnit 4를 사용하는 라이브러리가 있는지 확인해보시는 것을 추천드립니다.
아래 이미지에서는 IntelliJ의 Dependency Analyzer를 사용하고 있습니다.
보시면, jersey-test는 JUnit 4를 사용하고 있음을 알 수 있습니다. 즉, 저는 프로젝트에서 JUnit 4를 제거하더라도, Jersey의 이유로 JUnit 4를 사용할 수 있습니다. 가장 쉬운 방법은 jersey를 2.35로 업그레이드하는 것이지만, JUnit 5가 jersey-test 2.35에서 소개되었기 때문입니다. 하지만 저는 jersey-test 프레임워크를 업데이트할 수 없습니다. 다른 라이브러리들이 프로젝트에서 깨질 수 있기 때문입니다. 그래서 이 경우에 어떻게 해야 할까요?
I can exclude JUnit from Jersey with Dependency Exclusions from Maven (like the image below). That way JUnit 4 will not be used anymore, but rather our JUnit 5.
Jersey를 사용하는 어떤 테스트를 실행할 때, Jersey의 메서드들이 JUnit 4 애너테이션 setUp
과 tearDown
를 사용하고 있어서, @Before
와 @After
를 사용하여 로드되지 않습니다. 이를 해결하기 위해, JerseyTest
를 확장하고 setUp
과 tearDown
를 @BeforeEach
와 @AfterEach
로 구현하여 super.setUp()
와 super.TearDown()
를 호출하는 “Configuration Class”를 생성할 수 있습니다.
public class JerseyConfigToJUnit5 extends JerseyTest {
@BeforeEach
public void setUp() throws Exception {
super.setUp();
}
@AfterEach
public void tearDown() throws Exception {
super.tearDown();
}
}
이미 라이브러리를 확인했고, 누구도 JUnit 4 의 종속성을 더 가지고 있지 않다면, 마침내 모든 테스트를 JUnit 5로 이전할 수 있습니다. 이 과정에서 많은 작업을 절약해주는 좋은 도구가 있습니다. 바로 OpenRewrite입니다. 이는 소스 코드의 자동 리팩토링 생태계로, 모든 오래된 패키지와 오래된 어노테이션을 새로운 것으로 변경해줍니다.
이제 그就是这样, 너와 네 팀원들은 JUnit 5를 즐길 수 있으며, 새로운 테스트가 JUnit 5로 생성되고 프로젝트가 프랑켄슈타인이 되지 않을 것을 알고 마음을 편안하게 할 수 있습니다. 그러니 기억하세요, 프로젝트를 최신 상태로 유지하세요. 라이브러리를 잊으면 매일 업데이트가 점점 더 어려워질 것입니다. 항상 스펙을 따르는 스펙과 프레임워크를 사용하고, 코드에 좋은 설계를 가지세요. 이는 당신이 쉽게 변경하고 이동할 수 있게 해줍니다.
Source:
https://dzone.com/articles/junit-4-5-jupiter-vintage-how-to-deal