tools & libs/단위테스트(junit, spock)

[junit] jupiter 1. 기본 설정 및 활용

  • -

테스팅은 SW 개발의 필수적인 부분으로, 전문적으로 테스트만을 담당하는 직군이 존재할 정도로 그 중요성이 크다. 특히 TDD(Test Driven Development)나 BDD(Behavior Driven Development)와 같은 현대적인 개발 방법론들은 테스팅을 개발 과정의 핵심으로 두기도 한다. 그러나 모든 개발자가 테스트 전문가가 될 필요는 없다. 특히 애플리케이션 개발 시 기능별로 정확하게 동작하는지 검증하는 단위테스트는 개발자 간단히 수행할 수 있으며, 이는 SW 품질을 보장하는데 아주 중요한 역할을 한다.

이번 포스트에서는 Java 개발자들에게 가장 친숙한 단위테스트 프레임워크인 junit의 필요성과 간단한 사용법에 대해 살펴보자.

JUnit 5 User Guide

 

JUnit 5 User Guide

Although the JUnit Jupiter programming model and extension model will 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 cus

junit.org

 

 

테스트 자동화와 JUnit

 

테스트와 자동화 필요성

다음 처럼 나름 복잡한 메서드를 가진 Calculator 클래스를 생각해 보자.

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }

    public int divide(int a, int b) {
        return a / b;
    }
}

 

일반적으로 이 코드가 잘 동작하는지 확인하려면 호출해서 결과를 출력해 보게 된다.

public static void main(String[] args) {
  Calculator calculator = new Calculator();
  int result = calculator.add(10, 20);
  System.out.println(result);             // 결과가 30이군!
}

문제는 테스트 실행 결괏값을 텍스트로 확인해야 하고 또 시간이 지나면 결괏값이 무엇을 의미하는지 소스 코드를 분석해야 알 수가 있다. 즉 테스트 과정에서 시간이 너무 많이 걸리게 되고 자동화가 어렵다. 결과적으로 테스트를 등한시하게 된다. 이를 개선해서 테스트를 자동화하기 위한 도구가 JUnit이다.

 

기본 annotation

 

life cycle annotation

JUnit은 여러 annotation으로 테스트의 라이프사이클을 정의하는데 @Test와 @BeforeAll, @AfterAll, @BeforeEach, @AfterEach가 있다.

annotation description
@Test  가장 많이 사용되는 애너테이션으로 대상 메서드가 단위테스트를 수행하는 테스트 메서드임을 나타냄
@BeforeEach, @AfterEach 각각의 @Test 전/후에 공통적으로 처리할 사전/사후 작업 메서드 정의
@BeforeAll, @AfterAll 모든 @Test에 거쳐 한번 만 필요한 사전/사후 작업 메서드 정의. static 메서드에 작성

 

@DisplayName

@Test가 선언된 메서드의 검증 내용(목적)을 메서드 이름으로 사용하면 나중에 테스트 내용을 이해하기 용이하다. 하지만 메서드의 이름은 자바의 naming rule 상 필요한 내용을 작성하기에 한계가 많다.  이런 경우 @DisplayName을 이용하면 문자열 형태로 테스트 내용을 작성할 수 있다.

@Test
public void 두수를더해서나오는합을검증() {
  Calculator calculator = new Calculator();
  int result = calculator.add(1, 2);
  assertEquals(3, result);
}
@Test
@DisplayName("두 수의 합을 검증:예) 1+2=3")
public void addTest2() {
  Calculator calculator = new Calculator();
  int result = calculator.add(1, 2);
  assertEquals(4, result);
}

 

간단한 단위테스트

 

기본 설정

junit을 사용하기 위해서는 여러 가지 의존성이 필요한데 Junit Jupiter (Aggretator)를 사용하면 한 번에 다 가져올 수 있다.

Attregator는 junit-jupiter-api, junit-jupiter-params, junit-jupiter-engine을 포함한다.

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

위 라이브러리는 scope가 test로 설정되어 있으므로 maven을 사용 중이라면src/test/java에 테스트 코드를 작성해야 한다.

 

활용 예

 

package com.example.demo.junit;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.*;

@Slf4j
public class CalculatorTest {
    private Calculator calc;
    @BeforeEach
    public void setup(){
        log.debug("@BeforeEach - 개별 테스트에서 필요한 리소스 초기화");
        calc = new Calculator();
    }
    @AfterEach
    public void cleanup(){
        log.debug("@AfterEach - 개별 테스트에서 초기화했던 리소스 정리");
    }

    @BeforeAll
    public static void setupAll(){
        log.debug("@BeforeAll - 모든 테스트에서 공통적으로 사용할 리소스 초기화");
    }

    @AfterAll
    public static void cleanupAll(){
        log.debug("@AfterAll - @BeforeAll에서 초기화했던 리소스 정리");
    }


    @Test
    @DisplayName("두수를더해서나오는합을검증: ex) 1 + 2 = 3")
    public void 두수를더해서나오는합을검증(){
        int result = calc.add(10, 20);
        Assertions.assertEquals(result, 30);
    }

    @Test
    @DisplayName("나눗셈에 대한 연산 결과 검증: 100 / 2 = 50")
    public void divideTest(){
        int result = calc.divide(100, 2);
        Assertions.assertEquals(result, 50);
    }
}

단위테스트 실행 결과: 녹색은 퇴근!

 

테스트를 진행하면 @BeforeAll과 @AfterAll은 테스트 클래스의 모든 @Test에 걸쳐서 한번씩, @BeforeEach와 @AfterEach는 @Test마다  출력되는 것을 볼 수 있다.

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.