본문 바로가기
공부방

[TIL 06/26] 테스트

by hseong 2023. 6. 29.

1. 단위 테스트

단위 테스트는 일반적으로 함수 수준에서 특정 섹션의 기능을 검증하는 테스트를 말합니다.

  • 백엔드 엔지니어가 가장 집중해야하는 테스트
  • 가장 많이 작성해야 하고 가장 중요한 테스트
  • 특정 메서드가 예상대로 작동하는지 확인하기 위해 작성
  • 하나의 메서드에 여러 가지 테스트를 작성할 수 있으며 정상 흐름 뿐만 아니라 예외적인 상황에 대해서도 테스트를 수행한다.
  • 애플리케이션에서 가장 작은 단위의 테스트이며 보편적으로 하나의 클래스에 대해서 테스트하는 것이라 볼 수 있다.
  • 일반적으로 각 테스트에서 주어져야 하는 입력값 혹은 맥락이 있고(given), 테스트하고자 하는 대상 메서드(when), 검증하고자 하는 결과(then)이 있다.
  • 대체로 하나의 객체는 혼자서 일을 하지 않고 다른 객체들과 협력 관계를 맺고 있다. 이러한 협력 관계자들을 테스트 더블(대역)으로 교체해서 고립된 테스트를 진행하게 된다.

테스트 더블

  • 의존 구성 요소를 사용할 수 없을 때 테스트 대상 코드와 상호작용 하는 객체 즉, 가짜 객체이다.
  • 대표적인 가짜 객체가 Stub 과 Mock 객체이다.

단위 테스트 작성 목적

  • 소프트웨어가 지속적으로 변경될 때 발생하는 오류를 테스트 코드에 의해서 보호한다.
  • 테스트를 통해서 우리는 코드 개선에 대한 두려움을 줄일 수 있다. 리팩토링 수행 후에 올바르게 동작하지 않는다면 그냥 이전의 상태로 되돌리면 그만이다.
  • 테스트 코드는 그 자체로 하나의 명세가 된다. 다른 개발자는 내가 작성한 테스트만 읽어보고도 그것이 어떤 역할을 수행해야 하는지 파악할 수 있다.

2. JUnit 5

  • 과거의 JUnit 4는 하나의 모듈로 구성된 모놀리틱의 형태였다.
  • JUnit 5는 JUnit Platform, JUnit Jupiter, JUnit Vintage 세 가지의 모듈로 구성된다.
  • JUnit Platform
    • JVM에서 테스트 프레임워크를 시작하기 위한 기반 역할을 한다.
    • 플랫폼에서 실행되는 테스팅 프레임워크를 개발하기 위한 TestEngine API를 정의한다.
    • 테스트를 발견, 테스트 계획을 생성, TestEngine API를 통해 실제 테스트를 실행시키고 결과를 보고한다.
  • JUnit Jupiter
    • TestEngine의 실제 구현체이다.
    • JUpiter API를 통해 테스트를 작성하고 실행한다.
  • JUnit Vintage
    • JUnit 3 및 JUnit 4 기반 테스트를 실행하기 위한TestEngine을 제공한다.

3. 목과 스텁

  • 호출에 대한 기대를 명세한다.
  • 행위에 대한 검증을 위해 사용한다.
  • 메서드의 리턴 값으로 판단할 수 없는 경우 특정 동작을 수행하는지 확인하는 검증을 수행한다.

스텁

  • 가짜 객체

  • 실제 동작하는 것처럼 보이게 만드는 객체이다.

  • 인터페이스의 메서드를 구현해서 어떠한 결과를 반환하게 하고, 검증하고자 하는 객체의 상태를 확인하면서 올바르게 동작하는지 검증을 수행한다.

  • 목을 만들어서 스텁처럼 이용할 수도 있다.

  • 스텁은 모든 테스트 케이스에 대해 동작하지만 목은 우리가 지정한 행위에 대해서면 동작한다.

  • 다음은 BDDMockito를 이용한 스터빙과 행위에 대한 검증을 수행하는 코드이다.

    then(memberService).should().findMember(any());
given(memberService.findMember(any())).willReturn(member);

4. Spring Test

  • 스프링 프레임워크는 단위 테스트를 위한 몇 가지 목 객체와 테스트 지원 클래스를 제공한다.
  • 통합 테스트에 있어서 스프링은 강력한 기능을 가지고 있다.
  • Spring TestContext Framework는 ApplicationContext 인스턴스와 WebApplicationContext 인스턴스의 일관된 로딩과 컨텍스트 캐싱을 제공한다. 이를 통해 동일한 JVM 환경에서는 ApplicationContext가 한 번 로드된 이후부터 재사용을 통해 재빠른 후속 테스트 실행 속도를 보여준다.
  • 또한 의존성 주입, 트랜잭션 관리, 통합 테스트를 위한 클래스와 같이 유용한 기능을 제공한다.