JUnit5와 JUnit4를 같이 사용할 때 유의해야할 점
JUnit5와 JUnit4를 같이 사용할 때 유의해야할 점
배경 지식 - JUnit4 vs JUnit5
위의 2가지 글과 영상을 보시고, 최소한 "vintage-engine"이 무엇인지는 이해하고 이 글을 봐주셨으면 좋겠습니다.
JUnit5와 JUnit4를 같이 사용할때 주의 해야 할 점.
JUnit4를 사용한 테스트코드와 JUnit5를 사용하는 테스트코드가 같은 테스트 클래스에 있을때의 문제점
Q) 아래의 테스트 코드는 문제없이 돌아갈까요?
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import org.junit.Before;
import org.junit.jupiter.api.Test;
public class FailTest {
Integer integer = null;
@Before
public void setUp(){
integer = 1;
}
@Test
public void test() throws IOException{
assertEquals(1,integer);
}
}
만약, 자신있게 Yes라고 대답했다면... 이 글을 반드시 읽어 주시기 바랍니다. 😹
"JUnit5에 vintage-engine이 있으니까 JUnit4와 JUnit5를 혼용해서 사용해도 괜찮겠지?"
라는 생각으로 위 코드를 살펴보게 되면 사실 큰 문제는 없어보입니다. 하지만 실제로 테스트를 실행해보면 아래와 같이 setup이 제대로 되지 않은 것을 확인 할 수 있습니다.
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.Before;
import org.junit.jupiter.api.Test;
public class CalculatorTestFail {
Integer integer = null;
@Before // JUnit4에 정의되어 있는 Annotation ---[1]
public void setUp(){
integer = 1;
}
@Test // JUnit5에 정의되어 있는 사용하는 Annotation ---[2]
public void test() throws IOException{
assertEquals(1,integer); // JUnit5의 assertEquals() ---[3]
}
}
위의 테스트 코드는 2가지 문제점을 가지고 있습니다.
-
setUp()의 경우 JUnit4에 정의되어 있는 @Before를 사용한다.
-
하지만, @Test는 JUnit5에 정의되어 있는 것을 사용하고 있다.
즉, 서로 호환이 되지 않는 Annotation을 사용하고 있는 것이 가장 큰 문제점이죠.
vintage-engine을 통해서 기존의 JUnit4으로 만들어 둔 코드를 돌릴 수 있지만, JUnit5와는 별개로 실행된다는 것을 알 수 있습니다.
This is because each engine has its turn. Vintage engine discovers and runs the JUnit 4 tests. Jupiter runs its own discovery and execution phases where it discovers and executes JUnit 5 tests only. So not that you can only run JUnit 4 and JUnit 5 tests in the same project, you can also do that in the same test class.
출처 : https://igorski.co/mixing-junit-4-and-junit-5-tests/
실제로, 아래의 테스트 코드를 실행해보면
package com.eden6187.template;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.Before;
import org.junit.jupiter.api.BeforeEach;
public class SuccessTest {
Integer integer = null; // --- [4]
@BeforeEach
public void setUpUsingJunit5(){
System.out.println("State of Integer : " + integer);
this.integer = 1;
System.out.println("JUnit5 setup");
}
@Before
public void setUpUsingJunit4(){
System.out.println("State of Integer : " + integer);
this.integer = 1;
System.out.println("JUnit4 setup");
}
@org.junit.jupiter.api.Test
public void testCalcSum() {
assertEquals(integer,1);
System.out.println("JUnit5 test");
// --- [5]
}
@org.junit.Test
public void testCalcMultiply() {
assertEquals(integer,1);
System.out.println("JUnit4 test");
}
}
JUnit5가 먼저 실행이 되고, JUnit4가 실행이 되는 것을 알 수 있습니다.
위의 코드 [4]를 보시면 맴버 변수인 integer를 [5]에서 처럼 null로 초기화해주지 않아도
JUnit5 실행 이후 JUnit4 테스트를 다시 실행할 때 다시 null값이 들어 온 것을 확인 할 수 있습니다.
즉, JUnit4와 JUnit5가 서로 분리되어 실행 된다는 것을 알 수 있습니다.
결론
-
JUnit4로 작성된 레거시 코드가 있다면 한 클래스에 JUnit5를 혼용해서 사용하기 보다는 JUnit5를 사용하는 클래스를 따로 만들어주는 것이 좋을 것 같습니다.
-
vintage-engine을 통해서 기존의 JUnit4으로 만들어 둔 코드를 돌릴 수 있지만, JUnit5와는 별개로 실행된다는 것을 알 수 있습니다.
-
JUnit5와 JUnit4의 어노테이션을 섞어쓰지 않도록 하는게 좋을 것 같습니다.
Author And Source
이 문제에 관하여(JUnit5와 JUnit4를 같이 사용할 때 유의해야할 점), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@eden6187/JUnit5와-JUnit4를-같이-사용할-때-유의해야할-점저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)