노트

테스트 주도 개발 (TDD)

Test-Driven Development

설계#testing · 연결된 개념 12개

쉽게 말하면

TDD는 과녁을 먼저 세우고 화살을 쏘는 방식이에요. '이렇게 동작해야 한다'는 테스트를 먼저 실패시켜 두고, 맞힐 만큼만 코드를 쓴 뒤 정리하는 짧은 주기를 반복해요.

비유가 깨지는 곳 과녁 연습과 달리 TDD는 설계 기법이기도 해요. 테스트와 코드 사이 중복까지 없애다 보면 설계가 따라 나오고, 핵심은 늘 작은 보폭이 아니라 필요할 때 보폭을 줄일 수 있는 능력이에요.

코드를 쓰기 전에 실패하는 자동화된 테스트부터 쓰고, 그 테스트를 통과시킨 뒤 중복을 없애는 짧은 주기를 반복하는 개발 방식. 켄트 벡이 정리했다.

리듬

  1. 테스트를 하나 빠르게 추가한다
  2. 모든 테스트를 돌려 새 테스트가 실패하는지 확인한다(레드, Red)
  3. 통과할 만큼만 코드를 고친다(그린, Green)
  4. 모든 테스트가 통과하는지 확인한다
  5. 리팩터링으로 중복을 없앤다(리팩터, Refactor)

초록색으로 가는 세 가지 방법

  • 가짜로 구현하기(Fake It): 일단 상수를 돌려줘 통과시키고, 상수를 변수로 바꿔 가며 일반화한다
  • 삼각측량(Triangulate): 예제를 두 개 이상 만들어야 일반화한다. 어떻게 일반화할지 확신이 없을 때 쓴다
  • 명백한 구현(Obvious Implementation): 뻔하면 바로 제대로 짠다. 막히면 다시 작은 단계로 돌아간다

핵심은 늘 작은 단계를 밟는 것이 아니라 작은 단계를 밟을 수 있는 능력이다. 길이 미끄러우면 보폭을 줄이고 상황이 좋으면 늘린다. 떠오르는 할 일은 바로 하지 않고 목록(To-Do List)에 적어 둔다.

왜 중복인가

켄트 벡은 의존성이 문제 자체라면 중복은 그 증상이라고 본다. 테스트 코드와 실제 코드 사이의 중복까지 없애다 보면 설계가 따라 나온다. 그래서 TDD는 테스트 기법이자 설계 기법이다. 심플 디자인의 첫 규칙이 "테스트를 모두 통과한다"인 것도 같은 맥락이다.

  • 테스트를 먼저 쓰면 구현보다 인터페이스(어떻게 쓰일지)를 먼저 생각하게 된다
  • 남은 테스트들은 리팩터링의 안전망이 된다(자가 테스트 코드)
  • 버그를 고칠 때도 그 버그를 재현하는 실패 테스트부터 쓴다

컴포넌트 단위로 적용할 때는 React Testing Library, API는 DRF API 테스트을 참고.

출처: 『테스트 주도 개발』 켄트 벡 (원서 Test Driven Development: By Example)

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 테스트 냄새

    테스트 코드나 테스트 습관에서 나는, 더 깊은 문제를 알리는 신호. 제라드 메스자로스의 xUnit 테스트 패턴 정리가 이름을 붙였다.

  • 『켄트 벡의 Tidy First?』 개요

    켄트 벡이 "코드를 바꾸기 전에 먼저 정리해야 할까?"라는 질문 하나를 붙잡고 쓴 얇은 책. 아주 작은 구조 변경인 정리의 기법, 언제 정리할지의 관리, 왜 그런지의 이론을 차례로 다룬다.

  • 정리(Tidying)

    동작을 바꾸지 않는 아주 작은 구조 변경. 켄트 벡은 리팩터링이라는 말이 "기능 개발 중간의 긴 공사"처럼 쓰이며 동작 보존 원칙이 흐려지자, 더 작고 겁나지 않는 단위를 정리라는 이름으로 따로 불렀다. refactoring의 부분집합이다.

  • 러버덕 디버깅

    문제를 남에게(혹은 고무 오리에게) 말로 설명하다 보면 스스로 답을 찾게 되는 디버깅 방법.

  • 도메인 주도 설계 (DDD)

    소프트웨어 구조를 기술이 아니라 해결하려는 업무 영역(도메인)의 개념을 중심으로 짜는 설계 접근. 에릭 에반스(Eric Evans)가 2003년 같은 이름의 책에서 정리했다. 코드의 구조와 언어가 업무의 구조와 언어를 닮게 만드는 것이 목표다.

보기 옵션