castle.log
GitHub

테스트하기 쉬운 코드의 조건

2026년 05월 17일  3개월 전
테스트
품질
구조

테스트하기 쉬운 코드는 테스트 파일을 많이 붙인 코드가 아니라, 변경했을 때 어디를 확인해야 하는지 분명한 코드에 가깝다. 특히 프론트엔드에서는 DOM, API 호출, 전역 상태가 한 함수 안에 섞이면 테스트도 어려워지고 장애가 났을 때 원인도 늦게 잡힌다.

이 글은 프론트엔드 코드를 기준으로 테스트하기 쉬운 구조를 만들 때 자주 보는 조건을 정리한다.


1. 순수 함수

같은 입력에 대해 항상 같은 출력을 반환하고, 외부 상태를 바꾸지 않는 함수는 가장 테스트하기 쉽다.

  • 예시:
    // 순수 함수 예시
    function add(a: number, b: number): number {
      return a + b;
    }
    
  • 테스트 용이성:
    • 외부 상태에 의존하지 않기 때문에 독립적으로 테스트 가능
    • DOM 조작, API 호출 등이 없는 함수는 mocking 없이도 테스트 가능

2. 역할을 작게 나누기

하나의 함수나 모듈이 하나의 역할만 맡으면 테스트 범위도 작아진다.

  • 예시 (나쁜 예):

    async function fetchAndRenderUser(id: string) {
      const res = await fetch(`/api/users/${id}`);
      const data = await res.json();
      document.querySelector("#username").textContent = data.name;
    }
    
  • 개선된 예:

    async function fetchUser(id: string) {
      const res = await fetch(`/api/users/${id}`);
      return await res.json();
    }
    
    function renderUser(user: { name: string }) {
      document.querySelector("#username").textContent = user.name;
    }
    
  • 테스트 용이성:

    • 각 함수가 독립적으로 작동 → 각각 단위 테스트 작성이 쉬움

3. 예측 가능한 코드

  • 작성 팁:
    • 명확한 변수명
    • 일관된 스타일
    • 사이드 이펙트 제거
    • 예외 상황 최소화
  • 예시 (예측 불가능한 코드):
    let count = 0;
    function unpredictable() {
      return ++count;
    }
    
  • 예측 가능한 코드 예:
    function predictable(a: number, b: number): number {
      return a + b;
    }
    

테스트를 위해 코드를 바꿔도 될까?

  • 지양해야 하는 예:

    • 테스트를 위해 privatepublic으로 변경
    • 테스트용 메서드 추가 등
  • 권장하는 접근:

    • 테스트가 어려운 코드는 리팩토링이 필요한 신호
    • 의존성 분리, 모듈화 등으로 테스트 가능하도록 개선

정리

조건설명
순수 함수외부 상태에 의존하지 않음, 독립적인 테스트 가능
단일 책임 원칙하나의 역할만 하도록 설계, 테스트가 명확해짐
예측 가능한 코드테스트 시 의도치 않은 결과 방지
리팩토링 관점테스트가 어렵다면 코드 자체를 개선할 시점