JUnit5와 JUnit4를 같이 사용할 때 유의해야할 점

eden6187·2021년 8월 26일
9

Testing

목록 보기
1/1
post-thumbnail

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가지 문제점을 가지고 있습니다.

  1. setUp()의 경우 JUnit4에 정의되어 있는 @Before를 사용한다.

  2. 하지만, @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의 어노테이션을 섞어쓰지 않도록 하는게 좋을 것 같습니다.

0개의 댓글