Spring Boot/JUnit5

[JUnit 5] JUit5

수수한개발자 2022. 7. 21.
728x90

테스트 코드

테스트 코드의 중요성

  • 개발단계 초기의 문제 발견을 도와줍니다.
  • 개발자가 나중에 코드를 리팩터링 하거나, 기존 기능을 업그레이드하는 과정에 올바르게 작동하는지 확인할 수 있습니다.
  • 기능의 불확실성을 감소할 수 있습니다.
  • 시스템에 대한 실제 문서를 제공합니다. 즉, 단위 테스트 자체가 문서로 사용할 수 있습니다.

 

테스트 코드 적용 후 느낀 첫 번째 : 빠른 피드백 및 자동 검증

기존의 개발 방식은 다음과 같았다고 합니다.

 

  1. 코드 작성
  2. 서버(Tomcat, 내장 서버) 실행
  3. API 테스트 도구(Postman)로 HTTP 요청 및 응답을 눈으로 확인
  4. 결과가 다르면 서버 중지 후 코드 수정

여기서 매번 코드를 수정할 때마다 2번~4번을 반복했다고 합니다. (이건 저도 똑같네요ㅎㅎ)

따라서, 매번 서버를 내렸다 올리면서 1분 이상 시간이 소요되고, 눈으로 수동 검증을 하게 됩니다.

 

그러나 테스트 코드는 이런 수동 검증을 자동 검증이 가능하게 해 줍니다.

 

테스트 코드 적용 후 느낀 두 번째 : 기능의 안정성

 

새로운 기능이 추가되면 기존의 기능에 문제가 생긴 것을 발견할 수 있습니다. 

사실 이러한 문제는 제가 하고 있는 서비스에서도 종종 발생하는 일입니다.

 

그러나, 하나의 기능으로 전수 테스트를 하기에는 비용이 많이 드는 일입니다.

따라서 테스트 코드는 기존 기능이 잘 작동되는 것을 보장해주는 것입니다.

 


 

저는 개발하면서 기술도 중요하지만 이와 더불어 중요한 덕목이 안정성이라고 생각합니다.

어떠한 서비스를 하든 간에 안전하지 않다면 사용하기엔 그만한 위험 부담이 따릅니다.

그렇기 때문에 기업에서도 테스트 코드의 중요성이 강조되는 거라 봅니다.

 

테스트 코드 작성을 도와주는 프레임워크들이 있는데,

가장 대중적인 것으로는 xUnit 이 있습니다.

 

xUnit : 개발환경(x)에 따라 Unit 테스트를 도와주는 도구

  • JUnit : java 환경의 테스트 프레임워크
  • DBUnit : DB 환경의 테스트 프레임워크
  • CppUnit : C++환경의 테스트 프레임워크
  • NUnit :. net환경의 테스트 프레임워크

 

이 중 저는 자바 개발자로 업을 하고 있어 JUnit을 사용하겠습니다.

JUnit은 계속해서 개선 중이며, 최근에는 버전 5까지 출시했습니다.

 

JUni5

이전 JUni 버전과 다르게, JUnit5는 세 개의 서브 프로젝트로 이루어져 있다.

JUnit5은 Junit Platform + JUnit Jupiter + JUnit Vintage 이 세 개가 합친 것이다.

 

Junit Platform 

Junit Platform은 JVM에서 테스트 프레임워크를 실행하는데 기초를 제공한다. 또한 TestEngineAPI를 제공해 테스트 프레임워크를 개발할 수 있다.

 

JUni Jupiter

JUni Jupiter는 JUnit5에서 테스트를 작성하고 확장을 하기 위한 새로운 프로그래밍 모델과 확장 모델의 조합이다.

 

JUni Vintage

JUni Vintage는 하위 호환성을 위해 JUnit3와 JUnit4를 기반으로 돌아가는 플랫폼에 테스트 엔진을 제공해준다.

 

JUnit5은 java 8 이상부터 지원하며, 이전 버전으로 작성된 테스트 코드여도 컴파일이 정상적으로 지원된다.

 

기본 어노테이션

 

 

@BeforAll

이 어노테이션은 테스트가 실행되기 전 딱 한 번만 실행된다.

 

@AfterAll

이 어노테이션은 테스트가 끝난 후 딱 한 번만 실행된다.

 

@BeforEach

각각의 테스트 메서드가 실행되기 전 실행된다.

@Test, @RepeatedTest, @ParamterizedTest, @TestFactory 가 붙은 테스트 메소드가 실행되기 전 실행된다. 

JUnit4의 @Before와 같은 역할을 한다. 개인적으로 테스트하기 전에 필요한 목업 데이터를 미리 세팅해주기 위해 주로 사용한다.

 

@AfterEach

@Test, @RepeatedTest, @ParamterizedTest, @TestFactory 가 붙은 테스트 메서드가 붙은 테스트 메소드가 실행되고 난 후 실행된다.  JUnit4의 @After와 같은 역할을 한다.

 

 

package me.jisu.javatest;

import org.junit.jupiter.api.*;

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

class StudyTest {

    @Test
    void create() {
        Study study = new Study();
        assertNotNull(study);
        System.out.println("create");
    }

    @DisplayName("테스트 create1")
    @Test
    void create1() {
        System.out.println("create1");
    }

    /**
     *@BeforeAll  : 전체 테스트가 실행 되기 전
     *@AfterAll   : 전체 테스트가 실행된 후
     *@BeforeEach : 각각의 테스트 시작 전
     *@AfterEach  : 각각의 테스트 시작 후
     * 테스트들이 실행 될때 한번만 실행 된다.
     * 반드시 static void로 작성하면된다.
     */

    @BeforeAll
    static void beforeAll() {
        System.out.println("before all");
    }

    @AfterAll
    static void afterAll() {
        System.out.println("after all");
    }

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

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

 

위의 테스트를 돌렸을 때 아래와 같은 결과가 나온다.

 

@DisplayNameGeneration

테스트 클래스에 선언한다. 

  • standard: 메서드 이름과 그 뒤에 붙는 괄호 그대로 보여준다.
  • Simple : 메소드 이름만 보여준다.
  • ReplaceUnderscores : 언더스코어를 제거한다. create_new_study create new study로 보여준다.
  • IndicativeSentences : 테스트 클래스 이름과 테스트 메서드 이름 + 괄호를 보여준다.
class StudyTest {

    @Test
    void create_new_study() {
        Study study = new Study();
        assertNotNull(study);
        System.out.println("create");
    }

   
    @Test
    void create_new_study_agian() {
        System.out.println("create1");
    }

 

 

기본적으로 테스트 이름은 메서드 이름을 따라간다. 테스트 클래스 위의 @DisplayNameGeneration 을해 주면 밑의 결과가 나온다.

@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {

    @Test
    void create_new_study() {
        Study study = new Study();
        assertNotNull(study);
        System.out.println("create");
    }


    @Test
    void create_new_study_agian() {
        System.out.println("create1");
    }

 

@DisplayName

 

테스트 클래스와 테스트 메서드를 개발자가 보기 좋게 변경해줄 수 있다. 이모지도 가능하다.

 

@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class StudyTest {

    @Test
    void create_new_study() {
        Study study = new Study();
        assertNotNull(study);
        System.out.println("create");
    }

    @DisplayName("테스트 메소드 \uD83D\uDe31")
    @Test
    void create_new_study_again() {
        System.out.println("create1");
    }

테스트 메소드 이름으로 결과가 나오기 때문에 메서드 이름이 결과가 길어지기 때문에 @DisplayName으로 메서드마다 정해주는 것이 좋을 것 같다.

728x90

'Spring Boot > JUnit5' 카테고리의 다른 글

[JUnit5] 테스트 순서  (0) 2022.07.22
[JUnit5] 테스트 인스턴스  (0) 2022.07.22
[JUint5] 테스트 반복하기  (0) 2022.07.22
[JUnit5] Assumptions  (0) 2022.07.21
[JUnit5] Assertion  (0) 2022.07.21

댓글