본문 바로가기
Dev/테스트 코드

단위 테스트 기초

by 싯벨트 2025. 2. 23.
728x90

단위 테스트

단위 테스트의 정의를 먼저 살펴보고, 이를 이해하기 위한 개념들을 살펴보겠습니다.

단위 테스트는 진입점을 통해 작업 단위를 호출한 후 그 종료점을 확인하는 자동화된 코드다.

  • 테스트 프레임워크를 통해 쉽게 작성할 수 있다.
  • 빠르게 실행할 수 있다.
  • 신뢰성이 높고 가독성도 좋아서 유지 보수하기 용이하다.
  • 코드가 변경되지 않는 한 동일한 결과를 보장한다.

작업 단위

단위 테스트(unit test)에서 "단위"란 시스템 내 작업 단위(unit of work) 또는 사용 사례(use case)를 의미합니다. 이때, 작업 단위의 시작인 진입점(entry point)로직을 실행하는 시작점을 의미하고, 종료점(exit point)작업 단위의 결과를 나타내며 테스트로 검사할 수 있는 지점을 의미합니다.

단위 테스트는 종료점마다 구성하는 것이 좋으며, 종료점의 3가지 형태와 각 형태에 따라 테스트 코드를 구성하는 기법은 아래와 같습니다.

종료점 형태와 테스트 코드 구성 기법

  1. 값 반환
    • 작업 단위를 실행하여 진입점 호출 → 실행 결과 값 확인
  2. 상태값을 변경
    • 어떤 것을 호출 → 다른 것을 호출하여 상태값 확인
    • 이전에 호출한 것을 다시 호출하여 상태값 확인
  3. 서드 파티를 호출(의존성 호출)
    • 모의 객체를 통해 테스트 결과 임의 조작

테스트 진입점과 종료점

의존성

의존성이란 단위 테스트 중 온전히 제어할 수 없는 것들을 의미합니다. 만약 쉽게 제어할 수 있거나, 메모리 내에서 실행되거나, 빠른 속도로 처리된다면 의존성이 아니라고 생각할 수 있습니다. 종료점 형태 중 3번이었던 서드 파티를 호출하는 경우가 대표적으로 의존성을 호출하는 경우이며, 그 외에 의존성에 해당하는 예시들은 아래와 같습니다.

  • 파일에 무언가를 기록
  • 네트워크와 통신
  • 다른 팀이 관리하는 코드
  • 데이터베이스에 접근하는 행위
  • 오래 걸리는 계산 작업

좋은 테스트란

테스트 실행 시 중요한 속성

단위 테스트든 통합 테스트든 테스트 코드를 짤 때는 가독성, 유지 보수성, 신뢰성을 확보하는 것이 중요합니다.

가독성“테스트를 읽고 이해하기 쉬운가”,

유지 보수성“테스트 코드를 유지 관리하는 것이 수월한가”,

신뢰성“리팩터링을 마음 놓고 할 수 있는가”로 이해할 수 있습니다.

좋은 테스트의 특징

좋은 테스트의 특징은 다음과 같습니다.

  • 테스트 작성자 의도를 이해하기 쉬워야 하며, 의미가 있어야 합니다.
  • 읽고 쓰기 쉬워야 한다
  • 테스트를 자동화할 수 있어야 한다.
  • 같은 조건에서 실행 결과는 항상 같아야 하며, 누구나 쉽게 실행할 수 있어야 한다.
  • 구체적인 결과를 제공하여 문제를 쉽게 파악하고 해결할 수 있어야 한다.

좋은 단위 테스트의 특징

좋은 테스트의 특징과 더불어 단위 테스트는 아래와 같은 특징을 갖습니다.

  • 빠르게 실행되어야 한다.
  • 테스트하는 코드의 모든 동작을 완벽하게 제어할 수 있어야 한다.
    (의존성 제거 - 파일 시스템, 네트워크, 데이터베이스 필요 없이 메모리 내에서 실행)
  • 다른 테스트와 독립적으로 완전히 분리된 환경에서 실행되어야 한다
  • 가능한 한 동기적이고 순차적으로 실행되어야 한다.(병렬 스레드 사용 금지)

단위 테스트 구현 시 팁

  1. 실제 의존성을 흉태 내는 가짜 의존성인 스텁을 활용해서 의존성에 접근하지 않고 테스트를 수행한다.
  2. 인메모리 데이터베이스 사용 시, SQL이 복잡할 경우 스텁을 사용하고, 통합 테스트는 실제 데이터베이스를 사용한다.
    (실제 운영 데이터베이스와 인메모리 데이터베이스의 기능 간 차이가 있을 수 있다.)
  3. 비동기 처리를 동기적인 방식으로 검증할 경우, 직접 콜백 함수를 호출하거나 비동기 작업 완료를 기다렸다가 처리한다.

통합 테스트

작업 단위를 의존성에서 격리한 단위 테스트와 달리, 통합 테스트는 실제 의존성을 완전히 제어할 수 없는 상태에서 작업 단위를 테스트하는 것입니다. 이때 의존성으로는 네트워크, 데이터베이스, 스레드, 외부 API, 다른 팀이 만든 모듈 등이 있을 수 있습니다.

TDD

테스트 주도 개발이란 실제 환경에서 사용할 코드를 작성하기 전에 테스트부터 작성하는 테스트 방법론입니다. 먼저 코드를 시작하기 전에 테스트가 실패하는 것을 확인하고, 이후 코드 추가 및 수정 등 작업을 통해 해당 테스트가 기능을 정확히 검증하도록 합니다.


단위 테스트를 작성할 때, 좋은 단위 테스트를 짜고 있는지 확인하기 위한 체크리스트를 첨부해보겠습니다.

단위 테스트 체크리스트

  • 2주, 2개월, 2년 전에 만든 테스트가 여전히 잘 돌아가는가?
  • 내가 2개월 전에 작성한 테스트를 팀 내 다른 동료가 실행했을 때 문제없이 결과를 받을 수 있는가?
  • 내가 만든 테스트가 수분 내로 전부 실행되는가?
  • 버튼 하나만 눌러서 내가 작성한 모든 테스트를 실행할 수 있는가?
  • 기본적인 테스트를 몇 분 내로 작성할 수 있는가?
  • 다른 팀 코드에 버그가 있어도 내 테스트는 통과하는가?
  • 내 테스트는 다른 실행 환경에서 실행해도 동일한 결과를 보장하는가?
  • 데이터베이스나 네트워크, 배포 없이도 내 테스트는 동작하는가
  • 하나의 테스트는 삭제, 이동, 변경해도 다른 테스트는 영향을 받지 않고 잘 실행되는가?

참고자료

'Dev > 테스트 코드' 카테고리의 다른 글

비동기 코드 단위 테스트  (0) 2025.03.16
격리 프레임워크  (0) 2025.03.07
모의 객체를 사용한 상호 작용 테스트  (0) 2025.03.04
의존성 분리와 스텁  (0) 2025.03.02
JEST 활용 단위 테스트 작성  (0) 2025.02.25