Gradle 빌드 환경에서 Junit 5 Test

최근에 Next-Step 자바지기님의 TDD, clean code 과정을 해나가면서 Spring 없이 Gradle 환경에서 Junit 5 테스트를 수행 해야 하는 일이 잦아졌다.

 

Gradle을 빌드하다보면 Junit 5을 dependencies에 추가했음에도 Test 메소드가 Gradle의 :test task (junit tests)를 타고 수행되지 못해 아래와 같은 에러가 뜨곤 한다.

 

에러의 이유는 다양하지만 그 중 junit-jupiter-engine이 테스트 코드를 인식하지 못해 에러의 원인이 되기도 한다.

Process 'Gradle Test Executor 1' finished with non-zero exit value 1

 


에러를 예방한다는 의미로, 제대로 Gradle 빌드 환경에서 Junit 5 test를 수행하는 방법을 알아보자

  • 이 글에서 다루고 있는 내용: Junit 5을 사용하여 테스트를 수행할 수 있도록 Gradle을 셋팅하는 법
  • 이 글에서 다루지 않는 내용: Gradle의 모든 셋팅법, Gradle의 명령어

 

1. 먼저 Gradle부터 준비하자

version 4.6 or higher of the build tool is installed since that is the earliest version that works with JUnit 5.

 

  • Junit 5을 빌드하려면 4.6 버전 이상의 Gradle이 필요하다. 설치는 이 링크
  • Gradle 버전은 프로젝트 위치에서 연 bash나 shell에서 gradle -v 을 통해 확인할 수 있다.
$> gradle -v
------------------------------------------------------------
Gradle 7.0.6
------------------------------------------------------------

 

2. build.gradle 파일에 Gradle을 구성

build.gradle 파일에 Test task를 추가하면 Gradle에서 Test Task를 수행할 수 있다.
우리는 Junit 플랫폼을 사용할 것임으로 아래와 같은 코드를 build.gradle 파일에 추가해준다.

test {
    useJUnitPlatform()
}

 

3. 이제 JUnit Dependency를 추가해야 한다. 단 Junit 5는 그 전과 다르다.

build.gradle 파일에 JUnit Dependency를 추가해준다.

  • 여기서 JUnit 5이 달라진 점은 JUnit의 API 부분과 실행가능하도록 만들어 주는 런타임 플랫폼이 구분되었다는 점이다.
  • 이 구분된 런타임 플랫폼은 JUnit 5 Official User Guide1.1 What is JUnit 5 에 잘 설명 되어 있다.

본문은 아래와 같다. JUnit 5을 사용하는 것이 목적이라면 Dependencies 코드 부분까지 넘어가는 것을 추천한다.

1.1 What is JUnit 5?

Unlike previous versions of JUnit, JUnit 5 is composed of several different modules 
from three different sub-projects.

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

The JUnit Platform serves as a foundation for launching testing frameworks on the JVM. 
It also defines the TestEngine API for developing a testing framework that runs 
on the platform. Furthermore, the platform provides a Console Launcher 
to launch the platform from the command line and a JUnit 4 based Runner 
for running any TestEngine on the platform in a JUnit 4 based environment.

JUnit Jupiter is the combination of the new programming model and extension model 
for writing tests and extensions in JUnit 5. The Jupiter sub-project provides 
a TestEngine for running Jupiter based tests on the platform.

JUnit Vintage provides a TestEngine for running JUnit 3 and JUnit 4 based tests 
on the platform.
  • 보자면 JUnit 5은 그 전과 달리 3개의 서브젝트로 구성되어 있다는 내용이다.
  • 3개의 서브 프로젝트들은 JUnit Platform, JUnit Jupiter, JUnit Vintage이다.
    • JUnit Platform은 JVM에서 JUnit이 동작할 수 있도록 프레임워크를 인스턴스화 해주는 기반이다.
    • JUnit Jupiter는 JUnit 플랫폼 위에서 테스트를 동작하는 엔진이다. 개발자가 테스트 코드를 집중 할 수 있게 하고 다른 API를 사용해 테스트를 확장하는 것을 가능케 해준다.
    • JUnit Vintage는 이전 버전들 JUnit 3, JUnit 4의 테스트 엔진이다.

 


결국, 우리는 JUnit의 클래스와 메소드들을 사용하기 위한 JUnit API와 Runtime Platform인 Jupiter API, 두 개의 dependency를 추가해야한다.

  • Jupiter-API는 테스트 수행을 위해 testImplementation으로 추가해준다.
  • Jupiter-engine은 RuntimeOnly로 추가해준다.

Build.gradle 파일에 아래와 같이 dependencies를 추가해준다. 

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}

 

4. 끝, 이제 실전 테스트다.

  • TestExample.java를 만들어 아래 코드로 테스트 해보자.
  • 다음과 같은 명령어를 활용해 테스트 해볼 수 있다. $ gradle clean test
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class TestExample {
    @Test
    public void testAdd() {
        assertEquals(42, Integer.sum(19, 23));
    }

    // assertThrows 는 Throws Exception 테스트의 이전 스타일을 대체하는 JUnit5의 새로운 기능이다.
    @Test
    public void testDivide() {
        assertThrows(ArithmeticException.class, () -> {
            Integer.divideUnsigned(42, 0);
        });
    }
}

 

성공!! Test의 성공은 언제나 기분이 좋다!

 

 

 


추가) JUnit 3이나 JUnit 4를 같이 사용해야하는 경우

build.gradle 파일의 Dependencies 부분에 아래 코드를 추가해준다.

testCompileOnly 'junit:junit:4.12' 
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.3.1'

 

참고

+ Recent posts