테스팅(Testing)_JUnit을 사용한 단위 테스트

김예인·2023년 7월 4일

백엔드 공부일지

목록 보기
40/43
post-thumbnail

Junit

Java 언어 애플리케이션을 테스트하기 위한 오픈 소스 테스트 프레임워크
사실상 Java의 표준 테스트 프레임워크


Junit 기본 작성법

1. 기본 구조

import org.junit.jupiter.api.Test;

public class JunitDefaultStructure {

    @Test // @Test 애너테이션
    public void test1() { // void 타입의 메서드
        // 테스트하고자 하는 대상에 대한 테스트 로직 작성
    }

    @Test
    public void test2() {
        // 테스트하고자 하는 대상에 대한 테스트 로직 작성
    }

    @Test
    public void test3() {
        // 테스트하고자 하는 대상에 대한 테스트 로직 작성
    }
}

2. Assertion 메서드

Assertion과 관련된 다양한 메서드로 테스트 대상에 대한 Assertion을 진행

  • asserEquals() : 기대하는 값과 실제 결과 값이 같은지 검증

💻 예시

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

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

public class HelloJUnitTest {
    @DisplayName("Hello JUnit Test")  // 테스트 실행 결과창에 표시되는 이름 지정
    @Test
    public void assertionTest() {
        String expected = "Hello, JUnit";
        String actual = "Hello, JUnit";

        assertEquals(expected, actual); // (2)
    }
}


  • asserNotNull() : Null 여부 테스트

💻 예시

import com.codestates.CryptoCurrency;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

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

public class AssertionNotNullTest {

    @DisplayName("AssertionNull() Test")
    @Test
    public void assertNotNullTest() {
        String currencyName = getCryptoCurrency("ETH");

		// arrertNotNull(테스트 대상 객체, 실패시 표시 메시지)
        assertNotNull(currencyName, "should be not null"); // passed
    }

    private String getCryptoCurrency(String unit) {
        return CryptoCurrency.map.get(unit);
    }
}

  • assertThrows() : 호출한 메서드의 동작 과정 중에 예외가 발생하는지 테스트

💻 예시

import com.codestates.CryptoCurrency;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

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

public class AssertionExceptionTest {

    @DisplayName("throws NullPointerException when map.get()")
    @Test
    public void assertionThrowExceptionTest() {
    
        //assertThrows(발생이 기대되는 예외 클래스, 테스트 대상 메서드 호출하는 람다 표현식)
        assertThrows(NullPointerException.class, () -> getCryptoCurrency("XRP"));
    } // passed

    private String getCryptoCurrency(String unit) {
        return CryptoCurrency.map.get(unit).toUpperCase();
    }
}

Executable 함수형 인터페이스
void execute() throws Throwable; 메서드 하나만 정의되어 있으며, 파라미터를 받지 않고 리턴값이 없다.
람다 표현식이나 메서드 참조를 이용하여 실행할 코드를 정의한다.


3. 테스트 케이스 실행 전, 전처리

테스트 케이스 실행 전, 어떤 객체나 값에 대한 초기화 작업 등의 전처리

  • @beforeEach : 해당 메서드는 각 테스트 케이스 실행 직전에 먼저 실행되어 초기화 작업 등을 진행

💻 예시

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

import java.util.HashMap;
import java.util.Map;

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

public class BeforeEach2Test {
    private Map<String, String> map;

    @BeforeEach // 각 테스트 마다 실행 전 초기화 적용
    public void init() {
        map = new HashMap<>();
        map.put("BTC", "Bitcoin");
        map.put("ETH", "Ethereum");
        map.put("ADA", "ADA");
        map.put("POT", "Polkadot");
    }

    @DisplayName("Test case 1")
    @Test
    public void beforeEachTest() {
        map.put("XRP", "Ripple");
        assertDoesNotThrow(() -> getCryptoCurrency("XRP"));
    } // passed

    @DisplayName("Test case 2")
    @Test
    public void beforeEachTest2() {
        System.out.println(map);
        assertDoesNotThrow(() -> getCryptoCurrency("XRP"));
    }

    private String getCryptoCurrency(String unit) {
        return map.get(unit).toUpperCase();
    } // faild
}

  • BeforeAll() : 클래스 레벨에서 테스트 케이스를 한꺼번에 실행시키면 테스트 케이스가 실행되기 전에 딱 한 번만 초기화

💻 예시

public class BeforeAllTest {
    private static Map<String, String> map;

    @BeforeAll // 모든 테스트 케이스 실행 전 딱 한번만 초기화
    public static void initAll() {
        map = new HashMap<>();
        map.put("BTC", "Bitcoin");
        map.put("ETH", "Ethereum");
        map.put("ADA", "ADA");
        map.put("POT", "Polkadot");
        map.put("XRP", "Ripple");

        System.out.println("initialize Crypto Currency map"); // 콘솔에 딱 한 번만 출력됨
    }

    @DisplayName("Test case 1")
    @Test
    public void beforeEachTest() {
        assertDoesNotThrow(() -> getCryptoCurrency("XRP"));
    } // passed

    @DisplayName("Test case 2")
    @Test
    public void beforeEachTest2() {
        assertDoesNotThrow(() -> getCryptoCurrency("ADA"));
    } //passed

    private String getCryptoCurrency(String unit) {
        return map.get(unit).toUpperCase();
    }
}

4. 테스트 케이스 실행 후, 후처리

  • @AfterEach : 각 테스트마다 실행 후 초기화
  • @AfterAll : 모든 테스트 종료 후 딱 한 번만 초기화

5. Assumption을 이용한 조건부 테스트

특정 환경에만 테스트 케이스가 실행되도록 하는 기능

  • assumeTrue()

💻 예시

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

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

public class AssumptionTest {
    @DisplayName("Assumption Test")
    @Test
    public void assumptionTest() {
    
        // assumeTrue() 의 파라미터가 참이면 아래 로직 실행
        assumeTrue(System.getProperty("os.name").startsWith("Windows"));
        System.out.println("execute?");
        assertTrue(processOnlyWindowsTask());
    }

    private boolean processOnlyWindowsTask() {
        return true;
    }
}
profile
백엔드 개발자 김예인입니다.

0개의 댓글