~ 4.2 스프링 부트 3와 테스트 코드

SummerToday·2024년 1월 31일
1
post-thumbnail
post-custom-banner

테스트 코드란?

작성한 코드가 의도대로 동작하고 예상치 못한 문제가 없는지 확인할 목적으로 작성하는 코드이다.
유지보수의 용이성, 코드 수정에 있어서의 편의성 등의 장점이 있다.

  • 테스트 코드는 test 디렉토리에서 작업 한다.

    테스트 코드에는 대표적으로 AAA패턴과 given-when-then 패턴이 존재한다.
    두 패턴은 구성 측면에서는 동일하지만 given-when-then 패턴이 사람이 읽기 더 쉽다.

    • AAA 패턴
      테스트 코드를 아래 3단계 순서로 구분하는 것을 말한다.

      • Arrange(준비)
        테스트를 실행하기 전에 필요한 것들을 준비한다. 예를 들어, 객체를 생성하거나, Mock 객체를 만들거나, 테스트 전에 호출되어야 할 API들을 호출하는 것들을 의미한다.

      • Act(실행)
        테스트 코드를 실행한다.

      • Assert(단언)
        실행한 코드가 예상한대로 동작했는지 확인한다. assertTrue(), assertThat() 등의 코드들이 해당한다.

Given-When-Then 패턴

  • Given
    테스트 실행을 준비하는 단계

  • When
    테스트를 진행하는 단계

  • Then
    테스트 결과를 검증하는 단계

  • Given-When-Then 패턴 테스트 코드 예시

스프링 부트 3와 테스트

스프링 부트는 애플리케이션을 테스트하기 위한 도구와 애너테이션을 제공한다.
spring-boot-starter-test 스타터에 테스트를 위한 도구들이 존재한다.

  • 스프링 부트 스타터 테스트 목록 (JUnit과 AssertJ를 가장 많이 사용)

    • JUnit : 자바 프로그래밍 언어용 단위 테스트 프레임워크

    • Spring Tset & Spring Boot Test : 스프링 부트 애플리케이션을 위한 통합 테스트 지원

    • AssertJ : 검증문인 어설션을 작성하는 데 사용되는 라이브러리

    • Hamcrest : 표현식을 보다 이해하기 쉽게 만드는 데 사용되는 Matcher 라이브러리

    • Mockito : JSON용 어설션 라이브러리

    • JsonPath : JSON 데이터에서 특정 데이터를 선택하고 검색하기 위한 라이브러리

JUnit이란?

JUnit은 자바 언어를 위한 단위 테스트 프레임워크이다.

단위 테스트
: 작성한 코드가 의도대로 작동하는지 작은 단위(메소드)로 검증하는 것을 의미한다.

  • JUnit의 특징

    • 테스트 방식을 구분할 수 있는 애너테이션을 제공.

    • @Test 애너테이션으로 메소드를 호출할 때마다 새 인스턴스를 생성, 독립 테스트 가능.

    • 예상 결과를 검증하는 Assertion Methods 제공.

    • 사용 방법이 단순하고 테스트 작성시간이 적다.

    • 자동 실행, 자체 결과를 확인하고 즉각적인 피드백을 제공.
  • Assertion Methods
    Assert method는 org.junit.jupiter.api.Assertions 라는 클래스에 static으로 존재하고, 이를 활용하여 단위 테스트를 진행 할 수 있다.
    Assert method는 테스트의 성공여부에 따라 AssertionError를 throw한다.

JUnit 단위 테스트 코드 작성 예 - 1

  • @DisplayName
    : 테스트 이름 명시.
  • @Test
    : 테스트를 수행하는 메소드임을 명시.
  • assertEquals(A,B)
    : 첫 번째 인수에는 기대하는 값, 두 번째 인수에는 실제로 검증할 값을 넣어준다.

JUnit은 테스트끼리 영향을 주지 않도록 각 테스트를 실행할 때마다 테스트를 위한 실행 객체를 만들고 테스트 종료 시 실행 객체를 삭제한다.

  • 테스트 코드 작동 확인


    테스트가 끝나면 콘솔창에 테스트 결과가 표시된다.
    단, 성공여부, 테스트 케이스의 이름, 테스트 실행 시간 정보를 확인하기 위해서는 체크 버튼을 눌러주어야 한다.


JUnit 단위 테스트 코드 작성 예 - 2

// JUnitCycleTest.java

import org.junit.jupiter.api.*;

public class JUnitCycleTest {

    @BeforeAll // 전체 테스트를 시작하기 전에 1회 실행하므로 메소드는 static으로 선언
    static void beforeAll() {
        System.out.println("@BeforeAll");
    }

    @BeforeEach // 테스트 케이스를 시작하기 전마다 실행
    public void beforeEach() {
        System.out.println("@BeforeEach");
    }

    @Test
    public void test1() {
        System.out.println("test1");
    }

    @Test
    public void test2() {
        System.out.println("test2");
    }

    @Test
    public void test3() {
        System.out.println("test3");
    }

    @AfterAll // 전체 테스트를 마치고 종료하기 전에 1회 실행하므로 static 선언
    static void afterAll() {
        System.out.println("@AfterAll");
    }

    @AfterEach //테스트 케이스를 종료하기 전마다 실행
    public void afterEach() {
        System.out.println("@AfterEach");
    }

}
  • @BeforeAll
    전체 테스트를 시작하기 전에 처음 한번만 실행된다. 주로 데이터베이스를 연결하거나 테스트 환경을 초기화 할 때 사용된다. 해당 애너테이션은 전체 테스트 실행 주기에서 한번만 호출 되어야하기 때문에 메소드는 static으로 선언되어야 한다.

  • @BeforeEach
    테스트 케이스를 시작 전 매번 실행된다. 테스트 메소드에서 사용하는 객체를 초기화 하거나 테스트에 필요한 값을 미리 넣을 때 사용될 수 있다. 각 인스턴스마다 메소드를 호출해야 하므로 static으로 선언되면 안된다.

  • @AfterAll
    전체 테스트를 종료하기 전 매번 실행된다. 주로 데이터베이스 연결을 종료하거나 공통적으로 사용하는 자원을 해제할 때 사용된다. 전체 테스트 실행 주기에서 한번만 호출되어야 하므로 메소드는 static으로 선언되어야 한다.

  • @AfterEach
    각 테스트 케이스를 종료 전 매번 실행된다. 테스트 이후에 특정 데이터를 삭제해야 하는 경우 사용될 수 한다. 각 인스턴스마다 메소드를 호출해야 하므로 static으로 선언되면 안된다.

  • JUnit 흐름

AssertJ로 검증문 가독성 높이기

  • AssertJ란
    JUnit과 함께 사용해 검증문의 가독성을 높여주는 라이브러리이다.
    Assertions.assertEquals(a+b,sum); // 기댓값과 비교값이 잘 구분이 안되는 Assertion 예
    assertThat(a+b).isEqualTo(sum); // 가독성이 좋은 AssertJ 예
    두번째 코드와 같이 AssertJ를 사용할 경우에는 a와 b를 더한 값이 sum과 같아야한다는 의미가 좀 더 명확하게 표현이 된다는 장점이 있다.
    • 자주 사용되는 메소드들

      • isEqualTo(A)
        A 값과 같은지 검증

      • isNotEqualTo(A)
        A 값과 다른지 검증

      • contains(A)
        A 값을 포함하는지 검증

      • doesNotContain(A)
        A 값을 포함하지 않는지 검증

      • startsWith(A)
        접두사가 A인지 검증

      • endWith(A)
        접미사가 A인지 검증

      • isEmpty()
        비어있는 값인지 검증

      • isNotEmpty()
        비어있지 않은 값인지 검증

      • isPostive()
        양수인지 검증

      • isNegative()
        음수인지 검증

      • isGreaterThan(1)
        1보다 큰 값인지 검증

      • isLessThan(1)
        1보다 작은 값인지 검증



해당 글은 다음 도서의 내용을 정리하고 참고한 글임을 밝힙니다.
신선영, ⌜스프링 부트 3 벡엔드 개발자 되기 - 자바 편⌟, 골든래빗(주), 2023, 384쪽

profile
IT, 개발 관련 정보들을 기록하는 장소입니다.
post-custom-banner

0개의 댓글