[ S3 U7 ] Spring MVC 테스팅(Testing)

정윤호·2023년 3월 8일
0

[ S3 U7 ] Spring MVC 테스팅(Testing)

학습목표

  • 테스트를 왜 하는지 이해할 수 있다.
  • 단위 테스트가 무엇인지 이해할 수 있다.
  • JUnit의 기본적인 사용법을 이해할 수 있다.
  • 슬라이스 테스트가 무엇인지 이해할 수 있다.
  • Spring에서의 슬라이스 테스트 방법을 알 수 있다.
  • Hemcrest의 기본적인 사용법을 이해할 수 있다.
  • Mockito의 기본적인 사용법을 이해할 수 있다.

단위 테스트(Unit Test)

테스트를 해야 되는 이유

  • 테스트 대상이 검증 과정에서 잘 통과하게 만들어 최대한 더 나은 결과를 얻기 위함
  • 모든 테스트가 100% 완벽하게 이루어질 수 없음
  • 다만, 테스트를 전혀 하지 않을 경우 수습하기 힘든 상황에 직면할 가능성이 높음


<애플리케이션의 일반적인 테스트 분류>

단위테스트(Unit Test)란?

  • 기능 테스트 : 애플리케이션을 사용하는 사용자 입장에서 애플리케이션이 제공하는 기능이 올바르게 동작하는지를 테스트
  • 통합 테스트 : 클라이언트 측 툴 없이 개발자가 짜놓은 테스트 코드를 실행시켜 애플리케이션이 기대했던 대로 동작을 하는지 테스트 하는 것
  • 슬라이스 테스트 : 애플리케이션을 특정 계층(API계층, 서비스계층, 데이터 액세스 계층)으로 쪼개어서 하는 테스트
  • 단위 테스트 : 애플리케이션의 핵심로직인 비즈니스 로직을 메서드 단위로 테스트

단위 테스트를 해야되는 이유

  • 테스트를 단순화 할 수 있음
  • 테스트 결과를 빠르게 확인할 수 있음
  • 작은 단위 테스트로 문제를 사전에 발견하여 해결할 수 있음

테스트 케이스(Test Case)란?
테스트를 위한 입력 데이터, 실행 조건, 기대 결과를 표현하기 위한 명세를 의미하며, 한마디로 메서드 등 하나의 단위를 테스트하기 위해 작성하는 테스트 코드

단위 테스트를 위한 F.I.R.S.T 원칙

  • Fast(빠르게)
  • Independent(독립적으로)
  • Repeatable(반복 가능하도록)
  • Self-validating(셀프 검증이 되도록)
  • Timely(시기 적절하게)

Given-When-Then 표현 스타일

  • BDD(Begavior Driven Development) 테스트 방식에서 사용하는 용어로 테스트 케이스의 가독성을 높이기 위해 given - when - then 표현 방법을 사용
  • Given
    • 테스트를 위한 준비과정을 명시할 수 있음
    • 테스트에 필요한 전제 조건들이 포함됨
    • 테스트 대상에 전달되는 입력 값(테스트 데이터)를 포함함
  • When
    • 테스트 할 동작(대상)을 지정
    • 단위 테스트에서 일반적으로 메서트 호출을 통해 테스트를 진행
    • 한두줄 정도로 작성이 끝나는 부분
  • Then
    • 테스트의 결과를 검증하는 영역
    • 일반적으로 예상하는 값(expected)과 테스트 대상 메서드의 동작 수행 결과(actual) 값을 비교해서 기대한대로 동작을 수행하는지 검증(Assertion)

Assertion이란?
Assertion은 ‘단언’, ‘단정’ 등으로 번역되지만, 테스트시 Assertion은 테스트 결과를 검증할 때 주로 사용되며 ‘예상하는 결과 값이 참(true)이길 바라는 것’이라고 할 수 있음


JUnit을 사용한 단위 테스트

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

JUnit을 사용한 테스트 케이스의 기본 구조

if (arr.length == 0) return arr;

		int left = 0;
    int right = arr.length - 1;

    return sort(arr, left, right);
	}

	//퀵 정렬 메서드
	private int[] sort(int[] arr, int left, int right) {
		//partition 메서드를 활용하여 정렬
    int part = partition(arr, left, right);
    if (left < part - 1) arr = sort(arr, left, part - 1);
    if (right > part) arr = sort(arr, part, right);

    return arr;
  }

	private int partition(int[] arr, int left, int right) {
    // 배열의 중앙을 기준으로
    int pivot = arr[(left + right) / 2];
    //좌측이 우측보다 작을 경우, 즉 아직 모든 배열을 순회하지 않은 경우 반복
    while (left <= right) {
      //좌측의 수가 기준점보다 작다면
      while (arr[left] < pivot) left++;
        //우측의 수가 기준점보다 크다면
        while (arr[right] > pivot) right--;
          if (left <= right) {
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
          }
    }
    return left;
  }

슬라이스 테스트(Slice Test)

학습목표

  • 슬라이스 테스트(Slice Test)의 의미를 이해할 수 있다.
  • Spring에서 지원하는 테스팅 기능을 이용해서 API 계층의 Controller를 테스트 할 수 있다.
  • Spring에서 지원하는 테스팅 긴응을 이용해서 데이터 액세스 계층의 Repository를 테스트 할 수 있다.

슬라이스 테스트란?

  • 애플리케이션 테스트의 단계 : 단위 테스트 → 계층 테스트 → 통합테스트
  • 슬라이스 테스트 : 각 계층에 구현해 높은 기능들이 잘 작동하는지 특정 계층만 잘라서 테스트하는 것

개발자가 통합 테스트까지 작성하면 정말 바람직하겠지만, 일정 상의 이유 등으로 통합 테스트는 대개 QA부서나 외부로 대체되는 경우가 많음

API 계층 테스트

API 계층 테스트의 대상은 대부분 클라이언트의 요청을 받아들이는 핸들러인 Controller임.

→ Spring에서는 Controller를 테스트하기 위한 편리한 방법들을 제공

Controller 테스트를 위한 테스트 클래스 구조

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

@SpringBootTest
@AutoConfigureMockMvc
public class ControllerTestDefaultStructure {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void postMemberTest() {
        // given 
        
        // when
        
        // then
    }
}

데이타 액세스 계층 테스트

데이터 액세스 계층 테스트는 Spring Data JPA, Spring Data JDBC, Spring JDBC 등 사용하는 기술에 따라 테스트 방법을 지원

데이터 액세스 계층 테스트를 하기 위한 한 가지 규칙

→ DB의 상태를 테스트 케이스 실행 이전으로 되돌려서 깨끗하게 만든다.

@DataJpaTest // 혹은 @DataJdbcTest
public class DataAccessLayerTest {
		@Test
		public void testA() {
				// (1-1) 데이터가 DB에 잘 저장되는지를 테스트하기 위해 한 건의 데이터를 DB에 저장
				// (1-2) DB에 잘 저장되었는지 DB에서 조회해서 결과를 확인
		}

		@Test
		public void testB() {
				// (2-1) 데이터가 DB에서 잘 조회 되는지를 테스트하기 위해 DB에서 조회
		}
}

Mockito & TDD

학습목표

  • Mock의 의미를 이해할 수 있다.
  • Mockito의 기본 사용법을 이해할 수 있다.
  • 비즈니스 로직의 단위 테스트에 Mockito를 적용할 수 있다.
  • Controller의 슬라이스 테스트에 Mockito를 적용할 수 있다.
  • TDD(Test Driven Devlopment)의 개념을 이해할 수 있다.

Mock이란

사전상 Mock의 의미
’Not real, but intended to be very similar to a real situation, substance etc’
진짜인 것처럼 보이도록 진짜와 유사한 상황이나 물건, 물질 등을 의미

테스트에서의 Mock = 가짜 객체

→ 단위 테스트나 슬라이스 테스트 등에 Mock 객체를 사용하는 것 = Mocking

테스트에서 Mock 객체를 사용하는 이유

  • 해당 계층 영역에 대한 테스트에 집중하기 위해
  • 테스트에 필요한 불필요한 계층 제외를 통한 성능 이점
  • 다른 계층과 단절되어 불필요한 과정을 줄일 수 있음

<기존 슬라이스 테스트 실행 흐름>

<Mock을 이용한 슬라이스 테스트 실행 흐름>

Mockito란?

Mockito란, Spring Framework에서 지원하는 Mocking 라이브러리

TDD(Test Driven Development, 테스트 주도 개발)란?

테스트를 먼저하고 구현은 그 다음에 한다.

profile
오늘 하루도 최선을 다하자!!

0개의 댓글