TDD의 핵심 원칙: Red, Green, Refactor

하리보·2024년 12월 7일

TDD의 핵심 원칙: Red, Green, Refactor

2.1 TDD의 세 가지 사이클

TDD(Test-Driven Development)는 Red-Green-Refactor라는 세 단계로 구성된 반복적인 사이클을 중심으로 진행됩니다. 이 과정은 개발자가 코드를 점진적으로 개선하며 높은 품질을 유지할 수 있도록 돕습니다.

1. Red: 실패하는 테스트 작성

  • 목표: 기능이 제대로 작동하지 않는 상태를 정의합니다.
  • 설명:
    • 구현하려는 기능에 대한 테스트를 작성합니다.
    • 아직 코드는 작성되지 않았으므로 테스트는 반드시 실패합니다.
    • 실패는 정상적인 상태로, 기능 요구사항이 코드로 아직 충족되지 않았음을 보여줍니다.
  • 예시:
    @Test
    void shouldReturnSumOfTwoNumbers() {
        Calculator calculator = new Calculator();
        int result = calculator.add(2, 3);
        assertEquals(5, result); // 실패: add() 메서드가 아직 구현되지 않음
    }

2. Green: 테스트를 통과시키는 최소한의 코드 작성

  • 목표: 테스트를 통과하는 최소한의 동작 코드를 작성합니다.
  • 설명:
    • 테스트를 통과하는 데 필요한 가장 간단한 코드만 작성합니다.
    • 복잡한 로직을 고민하지 않고, 우선 "작동"하는 코드를 만드는 것이 중요합니다.
  • 예시:
    public class Calculator {
        public int add(int a, int b) {
            return a + b; // 테스트를 통과하는 최소한의 코드
        }
    }

3. Refactor: 코드를 리팩터링하여 개선

  • 목표: 코드를 보다 깔끔하고 효율적으로 개선합니다.
  • 설명:
    • 테스트를 다시 실행해 리팩터링이 기존 기능을 깨뜨리지 않았는지 확인합니다.
    • 중복 코드 제거, 가독성 향상, 성능 최적화를 위해 코드를 정리합니다.
  • 예시:
    • 초기에는 단순히 테스트를 통과했지만, 이후에는 메서드 구조와 가독성을 개선합니다.
    public class Calculator {
        // 추후 더 복잡한 로직을 추가하더라도 유지보수하기 쉽도록 코드 정리
        public int add(int a, int b) {
            return a + b;
        }
    }

핵심 철학:
"작동하는 코드를 작성하라. 그리고 더 나은 코드를 만들어라."


2.2 TDD와 테스트 종류

TDD는 여러 테스트의 기본이 되는 단위 테스트(Unit Test)를 중심으로 진행됩니다. 하지만, 통합 테스트(Integration Test)와 E2E 테스트(End-to-End Test)와도 밀접한 관계가 있습니다.

1. 단위 테스트 (Unit Test)

  • 정의:
    코드의 가장 작은 단위(클래스, 메서드)를 테스트합니다.
  • 목적:
    • 코드의 개별 구성 요소가 의도한 대로 동작하는지 확인합니다.
    • 종속성 없는 환경에서 빠르고 반복적으로 실행됩니다.
  • TDD와의 관계:
    • TDD의 중심. 대부분의 TDD는 단위 테스트 작성으로 시작됩니다.
    @Test
    void shouldReturnPositiveNumber() {
        assertEquals(5, Math.abs(-5));
    }

2. 통합 테스트 (Integration Test)

  • 정의:
    여러 구성 요소(모듈, 서비스)가 상호작용할 때 올바르게 동작하는지 확인합니다.
  • 목적:
    • 시스템 간 데이터 흐름과 의존성을 검증합니다.
  • TDD와의 관계:
    • TDD 단계에서는 단위 테스트만 작성하는 것이 일반적이지만, 통합 테스트는 후속 단계에서 시스템 안정성을 보장하는 데 중요합니다.
    @Test
    void shouldSaveUserToDatabase() {
        User user = new User("test", "test@example.com");
        userRepository.save(user);
        assertTrue(userRepository.findById(user.getId()).isPresent());
    }

3. E2E 테스트 (End-to-End Test)

  • 정의:
    사용자 관점에서 애플리케이션의 전체 흐름을 테스트합니다.
  • 목적:
    • 시스템의 모든 구성 요소가 올바르게 연동되어 최종 사용자가 의도한 대로 작동하는지 확인합니다.
  • TDD와의 관계:
    • TDD는 일반적으로 E2E 테스트까지 포함하지 않지만, 전체 시스템 안정성을 확보하기 위해 중요합니다.
    • 자동화 도구(Selenium, Cypress 등)를 활용하는 것이 일반적입니다.

TDD와 테스트의 관계 정리

테스트 유형TDD에서의 역할주요 특징
단위 테스트(Unit)TDD의 핵심. 작은 단위 테스트빠른 피드백, 독립적인 실행 가능
통합 테스트시스템 검증에 사용모듈 간 상호작용 검증, 데이터베이스와의 통합 테스트
E2E 테스트최종 검증 단계에서 사용사용자의 실제 경험 시뮬레이션

마무리하며

TDD는 단순히 테스트를 작성하는 것이 아니라, Red-Green-Refactor 사이클을 통해 반복적으로 코드를 개선하고, 단위 테스트를 중심으로 개발 프로세스를 구조화합니다. 통합 테스트와 E2E 테스트는 TDD와 별개의 개념이지만, 최종적으로 TDD가 만들어낸 코드의 안정성을 보증하는 데 중요한 역할을 합니다.

profile
하리보의 개발 블로그

0개의 댓글