단위 테스트 구조

개요

단위 테스트는 SUT(System Under Test)의 특정 동작을 검증하는 데 목적이 있다. 이 글에서는 테스트 구조의 대표적인 패턴인 AAA 패턴과 그 변형, 테스트 작성 시 유의할 점과 안티패턴, 테스트 픽스처 관리와 명명법까지 설명한다.

개념 설명

AAA 패턴 (Arrange-Act-Assert)

  • Arrange (준비) : 테스트 대상 객체와 협력자 객체를 설정하고 초기 상태를 구성한다.
  • Act (실행) : 테스트 대상 메서드를 호출한다. 의존성 주입이 필요하면 이 시점에 전달한다. 반환 값이 있다면 이를 캡처한다.
  • Assert (검증) : 반환 값, 상태 변화, 협력자에 대한 호출 등을 검증한다.

Given-When-Then 패턴

  • Given → 준비 단계
  • When → 실행 단계
  • Then → 검증 단계

기술자 외 독자에게 더 직관적이기 때문에, 테스트를 문서화하거나 비즈니스 이해관계자와 공유할 때 유리하다. 구성상의 실질적인 차이는 없다.

테스트 안티패턴

  • 테스트 내 if 문 사용: 테스트가 복잡하다는 신호이며, 분리하는 것이 좋다.
  • Act 구절이 두 줄 이상인 경우
  • 테스트 간 높은 결합도
  • 불명확한 명명 (e.g. should be)
  • 과도하게 형식화된 명명 규칙

준비 구절이 큰 경우

  • Object Mother : 테스트에 자주 사용되는 오브젝트를 생성하는 유틸리티 클래스.
  • Test Data Builder : 유연한 방식으로 객체 속성을 설정하며 가독성을 높인다.

단일 동작의 다양한 결과

하나의 동작이 여러 결과를 낼 수 있다면, 이를 하나의 테스트로 검증하는 것이 좋다. 결과 간 상호 관련성이 있는 경우 특히 그렇다.

종료 구절

  • AAA 패턴에는 명시적 종료(tearDown)는 포함되지 않는다.
  • 보통 통합 테스트에서 사용되며, 별도 메서드로 분리하여 재사용한다.

구절 주석 처리

  • AAA 패턴을 따르고 구문이 명확하면 주석을 제거해도 된다.
  • 준비나 검증이 복잡하거나 여러 줄일 경우 주석을 유지해 가독성을 높인다.

테스트 명세

  • 테스트는 단순히 기능 목록이 아니라, 애플리케이션의 행위 명세여야 한다.

테스트 픽스처 관리

  • 픽스처는 테스트 간 영향을 주지 않아야 한다.
  • 예외적으로 통합 테스트에서는 생성자에서 픽스처를 생성할 수 있다.
  • 팩토리 메서드를 통해 픽스처 생성 코드를 재사용할 수 있다.

테스트 명명법

  • 테스트 이름에 SUT 의 메서드명을 포함하지 말 것.
  • 테스트는 기능 명세이지 코드 구현이 아니다.
  • 유틸리티 클래스처럼 비즈니스 로직이 없는 경우는 예외.

예제 코드 (Node.js)

JavaScript.js
describe("주문 기능", () => {
  it("주문 금액이 일정 이상이면 무료 배송 혜택이 주어진다", () => {
    // Arrange
    const orderService = new OrderService();
    const order = createOrder({total: 50000});

    // Act
    const result = orderService.checkFreeShipping(order);

    // Assert
    expect(result).toBe(true);
  });
});

용어 정의

  • AAA 패턴: 단위 테스트를 구조화하는 전형적인 방식으로, 준비(Arrange), 실행(Act), 검증(Assert) 세 단계를 분리해 테스트의 가독성과 명확성을 높인다.
  • Given-When-Then: AAA 패턴과 유사하지만, 비기술자에게 친숙한 용어를 사용하여 테스트를 문서화하는 데 유리하다.
  • Object Mother: 테스트에서 자주 사용하는 객체를 빠르게 생성하기 위한 유틸리티 클래스를 의미한다.
  • Test Data Builder: 복잡한 테스트 데이터를 유연하게 생성할 수 있도록 돕는 패턴이며, 빌더 패턴을 활용한다.
  • 픽스처(Fixture): 테스트 실행 전후에 필요한 상태나 데이터를 의미하며, 테스트 간 독립성을 보장하기 위해 관리가 중요하다.

정리

단위 테스트는 단순 검증을 넘어서 시스템 동작의 명세서 역할을 수행한다. AAA 패턴을 기본 구조로 사용하되, 테스트 가독성과 유지 보수성을 높이기 위해 적절한 패턴과 명명 규칙, 픽스처 전략을 적용하는 것이 중요하다.