공부방/JAVA

JUnit5을 이용한 테스트코드 작성 방법 - 1편

EVO. 2023. 8. 5. 01:44

JUnit5 소개


  • 자바 개발자가 가장 많이 사용하는 테스팅 프레임워크
  • 자바 8버전 이상을 필요로 합니다

 

JUnit 5의 구조


JUnit5 = JUnit Platform + Jupiter + Vintage 

  • Platform  
    • JVM에서 테스트 프레임워크를 실행하기 위한 런처를 제공
    • 플렛폼 상에서 테스트 프레임워크를 개발하고 실행하기 위한 TestEngine API 제공
    • 커맨드 라인에서 플랫폼을 실행하기 위한 Console Launcher 제공
    • JUnit4 기반 Runner 제공 
  • JUnit Jupiter
    • TestEngine API 구현체로 JUnit5를 제공
  • JUnit Vintage
    • JUnit 4와 3을 지원하는 TestEngine 구현체

 

JUnit5 시작하기


2.2+버전의 스프링부트 프로젝트를 만든다면 기본으로 JUnit5 의존성이 추가됩니다

만약 스프링 부트 프로젝트를 사용하지 않는다면 Maven을 쓰는 경우 pom.xml에서 다음과 같은 의존성을 추가하시면 됩니다

 

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.5.2</version>
    <scope>test</scope>
</dependency>

 

Annotations


JUnit5에서 제공되는 어노테이션은 상당히 많습니다. 그중에 가장 많이 이용되고 기본적인 것만을 소개하겠습니다

 

앞으로 소개드릴 어노테이션

  • @Test
  • @BeforeAll / @AfterAll
  • @BeforeEach / @AfterEach
  • @Disabled

활용 예제 

일단 해당 어노테이션들을 사용하기 위해 먼저 구현할 클래스를 생성합니다

간단한 계산 프로그램을 만든다고 가정해봅시다. 이 클래스는 생성될때 두개의 인자와 계산타입을 미리 받고 calculate메서드를 사용할때 계산되어 반환되는 프로그램입니다. 이를 이용해 테스트를 해볼 생각입니다

그리고나서 테스트 클래스를 생성하기 위해 Calculate 클래스에서 ctrl+shift+t를 하시고 확인버튼을 누르시면 됩니다


@Test

테스트 메서드임을 알립니다 

 @Test
    void plusTest(){
  }

단순히 테스트해볼 메서드에 어노테이션을 붙이면 단위테스트가 가능합니다. 또한 JUnit5부터는 public 접근제어자를 붙일 필요가 없어졌습니다

 


@BeforeAll / @AfterAll

테스트 시작 전,후 무조건 딱 한번 실행되는 메서드 입니다

 

출력 결과

BeforeAll
plusTest
after all

 


@BeforeEach / @AfterEach

현재 클래스의 모든 테스트 메서드를 실행하기 전, 후에 실행되어야 하는 메서드 입니다

 

출력 결과

BeforeAll
Before each
plusTest
After each
after all

@Disabled

전체 테스트를 진행했을 때 어떤 단위테스트는 테스트를 진행하지 않도록 하는 어노테이션 입니다


테스트 이름 표시하기


@DisplayNameGeneration

  • Method와 Class 레퍼런스를 사용해서 테스트 이름을 표기하는 방법을 설정합니다
  • 기본 구현체로 ReplaceUnderscores를 제공합니다

실행결과

테스트 한 이름이 underBar 대신 공백으로 바뀐채 실행되었습니다

 

이것보다 더 자주 쓰이는 어노테이션을 소개하겠습니다


@DisplayName

  • 어떤 테스트인지 테스트 이름을 보다 쉽게 표현할 수 있는 방법을 제공하는 어노테이션 입니다
  • @DisplayNameGeneration 보다 우선 순위가 높습니다

실행결과


JUnit5 : Assertion


검증하기 위한 메서드이며 가장 핵심적인 부분 입니다

실제 값이 기대한 값과 같은지 확인 assertEquals(expected, actual)
값이 null이 아닌지 확인 assertNotNull(actual)
다음 조건이 참(true)인지 확인 assertTrue(boolean)
모든 확인 구문 확인 assertAll(executables...)
예외 발생 확인 assertThrows(expectedType, executable)
특정 시간 안에 실행이 완료되는지 확인 assertTimeout(duration, executable)

assertNotNull

제공된 객체가 null이 아닌지 검사합니다 


assertEquals

첫번째 인자(기댓값)이 두번째 인자(실제값)과 동등한지 검사합니다 동등하지않으면 세번째 함수형인터페이스(Supplier)를 실행합니다.


assertTrue

제공된 인자가 true인지 검사합니다

 

assertTrue(plusCalculate.calculate()==30,"30이여만 한다.");

assertAll

  • Executable 목록을 가변인자로 전달받아 각 Executable을 모두 실행한 뒤, 모두 성공했는 지 검사 합니다
  • 실패한 Executable이 있다면, 실패한 검증 결과를 모아서 에러 메시지로 보여줍니다
  • 하나 실패하면 다른 assert 메서드를 실행안하는것을 막기위한 방법 입니다

실행결과

org.opentest4j.AssertionFailedError: 더하기 계산기 이므로 num1 과 num2가 더한 값이 나와야 한다. ==> 
필요:30
실제   :20

...

org.opentest4j.AssertionFailedError: 30이여만 한다. ==> 
필요:true
실제   :false

...

org.opentest4j.MultipleFailuresError: Multiple Failures (2 failures)
	org.opentest4j.AssertionFailedError: 더하기 계산기 이므로 num1 과 num2가 더한 값이 나와야 한다. ==> expected: <30> but was: <20>
	org.opentest4j.AssertionFailedError: 30이여만 한다. ==> expected: <true> but was: <false>

assertj 활용

assertj라이브러리를 활용하면 더 다양한 테스트가 가능합니다

실행결과

0보다 큰 결과가 나와야 하지만 아니여서 테스트 실패로 나오게 됩니다


JUnit 5 : 태깅과 필터링 


태그는 필터링 테스트를 위한 태그를 선언하는데 사용합니다

@Tag("fast")//로컬에서 테스트 가능할만큼 속도가 빨리 처리된다는 태그를 달아 놓은 것
@Tag("slow") // 로컬에서 실행하면 느리며 통합환경인 CI에서 테스트 할 수 있는 것

이런식으로 각 메서드에 상황에 맞게 적고나서 

테스트 configuration에서 fast라 적어주고 적용하면 로컬에서 실행할때 fast라 적은 태그들만 실행 합니다.

다음은 CI 서버에서 빌드를 할때 모든 테스트가 실행해야 하기 때문에 fast slow 태그들 모두 실행시키는 방법 입니다.

pom.xml에서 해당 태그를 넣어주면 됩니다

<profiles>
        <profile>
            <id>default</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <groups>fast</groups>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>ci</id>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <groups>fast | slow</groups>
                        </configuration>

                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

해당 태그에 대한 자세한 설명은 아래 사이트를 참조하시면 됩니다

https://maven.apache.org/guides/introduction/introduction-to-profiles.html

 

Maven – Introduction to build profiles

Introduction to Build Profiles Apache Maven goes to great lengths to ensure that builds are portable. Among other things, this means allowing build configuration inside the POM, avoiding all filesystem references (in inheritance, dependencies, and other pl

maven.apache.org

https://junit.org/junit5/docs/current/user-guide/#running-tests-tag-expressions

 

JUnit 5 User Guide

Although the JUnit Jupiter programming model and extension model do not support JUnit 4 features such as Rules and Runners natively, it is not expected that source code maintainers will need to update all of their existing tests, test extensions, and custo

junit.org

 

이제 터미널에서 다음과 같이 빌드를 하면 됩니다

./mvnw test -P ci

 

 

출처


https://www.inflearn.com/course/the-java-application-test/dashboard

 

더 자바, 애플리케이션을 테스트하는 다양한 방법 - 인프런 | 강의

자바 프로그래밍 언어를 사용하고 있거나 공부하고 있는 학생 또는 개발자라면 반드시 알아야 하는 애플리케이션을 테스트하는 다양한 방법을 학습합니다., 그냥 개발자를 넘어 '더 나은 개발

www.inflearn.com

https://velog.io/@jaehoonlee/JUnit-5-%EA%B3%B5%EC%8B%9D-%EA%B0%80%EC%9D%B4%EB%93%9C-%EB%AC%B8%EC%84%9C-%EC%A0%95%EB%A6%AC

 

JUnit 5 공식 가이드 문서 정리

JUnit 5 공식 가이드 문서 정리

velog.io