본문 바로가기

JAVA

JUnit5 User Guide 공부 #1

JUnit5 #1

Junit5 User Guide를 읽어보면서 Junit5를 공부하는 게시글입니다.

#2 바로가기, #3 바로가기

이번 게시글에서는 JUnit5의 특징과 라이프 사이클에 대해 알아보겠습니다.

Junit5란?

  • Junit5는 이전 버전과는 다르게 3가지의 서로 다른 하위 프로젝트들로 구성되어 있습니다.
  • 하위 프로젝트는 총 3개이며 아래와 같습니다.

 

  • 우리가 작성하는 테스트 코드는 JUnit Vintage 혹은 JUnit Jupiter에 의해 실행되며 IDE나 Build Tool은 JUnit Platform을 통해 해당 테스트들을 구동시킵니다.

1. JUnit Platform

  • JVM위에서 테스트를 실행시키는 기반 역할을 합니다.

2. JUnit Jupiter

  • JUnit5 기반의 테스트를 실행시키는 테스트 엔진을 제공합니다.

3. JUnit Vintage

  • JUnit3, 4로 작성된 테스트를 실행시키는 테스트 엔진을 제공합니다.

JUnit5는 자바 8 이상의 런타임 환경을 요구하지만 이전 버전으로 컴파일된 코드도 테스트할 수 있습니다.


테스트 작성하기

1. 의존성 추가 및 테스트 확인

plugins {
    id 'java'
}

group 'me.sun'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testImplementation('org.junit.jupiter:junit-jupiter:5.6.0')
}

test {
    useJUnitPlatform()
}
  • 우선 gradle기반의 자바 프로젝트에서 jupiter를 추가해주고 JUnitPlatform을 설정합니다.

 

import org.junit.jupiter.api.Test;

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

class SampleTest {
    @Test
    void sampleTest() throws Exception{
        assertEquals(10, sum(3, 7));
    }

    private int sum(int a, int b){
        return a + b;
    }
}
  • JUnit5는 위와 같이 class와 method에 따로 public을 붙이지 않고 간단하게 테스트를 진행할 수 있습니다.
  • public을 붙여도 되지만 private를 붙이면 테스트는 동작하지 않습니다.

2. Meta Annotaiton 사용

  • JUnit Jupiter Annotation들은 meta-annotaiton으로 사용될 수 있습니다.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@DisplayName("값을 더하는 테스트(MyTest Annotation)")
@Test
public @interface MyTest {
}
  • 즉 커스텀 애노테이션을 만들고 JUnit5 테스트에 적용시킬 수 있습니다.
  • Test Annotaiton과 해당 테스트 이름을 설정해주는 DisplayName Annotation을 MyTest Annotaiton에 추가하였습니다.

 

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

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

class SampleTest {

    @Test
    @DisplayName("값을 더하는 테스트")
    void sampleTest() throws Exception{
        assertEquals(10, sum(3, 7));
    }


    @MyTest
    void tempTest() throws Exception{
        assertEquals(10, sum(3, 7));
    }


    private int sum(int a, int b){
        return a + b;
    }
}
  • 해당 테스트를 실행시켜보면 아래와 같이 정상 동작하는 것을 확인할 수 있습니다.

3. 테스트 클래스와 라이프사이클

  • 우선 최상위의 테스트 클래스의 경우 최소 하나의 테스트 메서드를 가지고 있어야 합니다.
  • 그리고 테스트 클래스는 abstract를 정의할 수 없으며 single constructor가 존재해야 합니다.
  • 아래에서는 테스트 코드 라이프 사이클에 대해 확인해보겠습니다.
  • 해당 라이프사이클은 상속받은 클래스에도 적용될 수 있습니다.
import org.junit.jupiter.api.*;

class SampleTest {

    @BeforeAll
    static void beforeAll(){
        System.out.println("=========================== Before All ===========================");
    }

    @BeforeEach
    void beforeEach(){
        System.out.println("---------------------------- Before Each ----------------------------");
    }

    @Test
    void sampleTest1() throws Exception{
        System.out.println(">>>>>>>>>>>>>>>>>>>> 테스트 1 <<<<<<<<<<<<<<<<<<<<");
    }


    @Test
    void sampleTest2() throws Exception{
        System.out.println(">>>>>>>>>>>>>>>>>>>> 테스트 2 <<<<<<<<<<<<<<<<<<<<");
    }


    @AfterEach
    void afterEach(){
        System.out.println("---------------------------- After Each ----------------------------");
    }

    @AfterAll
    static void afterAll(){
        System.out.println("=========================== After All ===========================");
    }
}


// ============================ 출력 ==========================
=========================== Before All ===========================

---------------------------- Before Each ----------------------------
>>>>>>>>>>>>>>>>>>>> 테스트 1 <<<<<<<<<<<<<<<<<<<<
---------------------------- After Each ----------------------------


---------------------------- Before Each ----------------------------
>>>>>>>>>>>>>>>>>>>> 테스트 2 <<<<<<<<<<<<<<<<<<<<
---------------------------- After Each ----------------------------

=========================== After All ===========================
  • BeforeAll은 테스트 실행 시 해당 테스트 클래스의 최초를 뜻하고 AfterAll은 최후를 뜻합니다.
  • 해당 테스트 둘은 static 메서드로 작성하여야 테스트가 적용됩니다.
  • 각 Each는 각 테스트마다 적용되는 메서드입니다.

테스트 클래스 상속

public class TempTest extends SampleTest {

    @Test
    void tempTest() throws Exception{
        System.out.println("tempTest");
    }

}

// =========================== 출력 ===========================
---------------------------- Before Each ----------------------------
tempTest
---------------------------- After Each ----------------------------
  • 위에서 설명드렸듯이 테스트 클래스를 상속받으면 상속받은 클래스도 부모의 라이프사이클이 사용되는 것을 확인할 수 있습니다.