본문으로 건너뛰기

저자의 글

작동하는 깔끔한 코드(clean code that works). 이 한마디가 바로 테스트 주도 개발의 궁극적인 목표다. 작동하는 깔끔한 코드가 훌륭한 목표인 수많은 이유가 있다.

  • 예측 가능한 개발 방법이다. 끊임업이 발생할 버그에 대해 걱정하지 않고, 일이 언제 마무리될지 알 수 있다.
  • 코드가 가르쳐주는 모든 교훈을 학습할 기회를 갖게 된다. 처음 생각나는 대로 후딱 완료해 버리면 두 번째 것, 더 나은 것에 대해 생각할 기회를 잃게 된다.
  • 당신이 만든 소프트웨어는 사용자의 삶을 향상시켜 준다.
  • 동료들이 당신을 존경할 수 있게 해주며, 당신 또한 동료들을 존경할 수 있게 된다.
  • 작성하는 동안 기분이 좋다.

어떻게 하면 작동하는 깔끔한 코드를 얻을 수 있을까? 우리는 자동화된 테스트로 개발을 이끌어 가야한다. 이런 개발 방식을 테스트 주도 개발이라 부른다. 테스트 주도 개발에서는

  • 오직 자동화된 테스트가 실패할 경우에만 새로운 코드를 작성한다.
  • 중복을 제거한다.

두 가지 단순한 규칙만을 따른다. 이 단순한 규칙이 가지는 다음과 같은 기술적인 함의로 인해 개인이나 집단 차원의 복잡한 행동패턴이 만들어진다.

  • 매 결정사항에 대해 피드백을 제공하는 실행 가능한 코드를 기반으로 하는 유기적인 설계를 해야 한다.
  • 자동화된 테스트를 다른 사람이 만들어주길 하루에 스무 번도 넘게 기다릴 수는 없으므로, 직접 테스트를 작성해야 한다.
  • 개발 환경은 작은 변화에도 빠르게 반응할 수 있어야 한다.
  • 테스트를 쉽게 만들려면 반드시 응집도는 높고 결합도는 낮은 컴포넌트들로 구성되게끔 설걔해야 한다.

또한 위의 두 가지 규칙에 의해 프로그래밍 순서가 다음과 같이 결정된다.

  1. 빨강 - 실패하는 작은 테스트를 작성한다.
  2. 초록 - 빨리 테스트가 통과하게끔 만든다.
  3. 리팩토링 - 일단 테스트를 통과하게만 하는 와중에 생겨난 모든 중복을 제거한다.

이런 식으로 프로그래밍하는 게 가능하고, 코드의 결함률을 극적으로 낮춰줄 뿐 아니라, 코드가 정말로 깔끔해져서 팀원 누구나 코드를 쉽게 알아볼 수 있게 해준다고 가정해보자. 이와 같은 가정이 가능하다면, 실패하는 테스트를 통과시키기 위해 필요한 만큼만 코딩하는 것은 다음과 같은 사회적 함의도 갖게 될 것이다.

  • 결함 밀도를 충분히 감소시킬 수 있다면, QA를 수동적인 작업에서 능동적인 작업으로 전환할 수 있다.
  • 고약한 예외 상황의 숫자를 충분히 낮출 수 있다면, PM이 정확히 추정할 수 있어 고객을 매일의 개발 과정에 참여시킬 수 있다.

용기

테스트 주도 개발은 프로그래밍하면서 나타나는 두려움을 관리하는 방법이다. 여기서의 두려움은 "정말 어려운 문제라서 시작단계인 지금은 어떻게 마무리될지 알 수 없군"하고 생각하는 합리적인 두려움을 말한다.

테스트 하나를 작동하게 하면, 그게 지금 현재 그리고 앞으로 영원히 작동할 거라는 걸 알 수 있다. 테스트가 망가져 있을 때에 비해, 이제 모든 것이 작동하는 쪽으로 한 걸음 더 가까이 있다. 이제 다음 테스트를 작동하게 하고, 그 다음, 또 다음... 프로그래밍 문제가 어려울수록 각각의 테스트는 좀더 작은 부분을 커버해야 한다.

TDD란 프로그래밍 도중 내린 결정과 그 결정에 대한 피드백 사이의 간격을 인지하고, 또한 이 간격을 통제할 수 있게 해주는 기술을 말한다.

당신은 꿈도 못 꿀 만큼, 더 많은 테스트를 더 일찍 작성하고, 또 더 작은 단계로 작업하고 있다는 것을 깨닫게 될 것이다. 한편 몇몇 소프트웨어 엔지니어들은 TDD를 배운 후에 다시 원래 습관으로 돌아가서 작업하다가, 기존의 습관으로는 일이 진척되지 않을 때에만 TDD를 사용하게도 한다.

순수하게 TDD로만 풀어낼 수 없는 프로그래밍 작업이 분명히 있을 것이다. 예를 들면 보안 스프트웨어와 동시성은 TDD로 해당 소프트웨어의 목표가 달성되었다는 것을 기계적으로 보여주기에 부족한 두 가지 주제라고 할 수 있다.

일단 이 책을 끝까지 읽고 나면

  • 단순하게 시작하고
  • 자동화된 테스트를 만들고
  • 새로운 설계 결정을 한 번에 하나씩 도입하기 위해 리팩토링을 할 준비가 될 것이다.

이 책은 세 부로 구성된다.

  • 1부. Money 예제 - TDD로 일상적인 모델 코드를 만드는 예제. 이 예제를 통해 여러분은 코딩하기 전에 먼저 테스트를 만드는 법과 설계를 유기적으로 키워나가는(grow) 방법을 배우게 될 것이다.
  • 2부. xUnit 예제 - 자동화된 테스트를 위한 프레임워크를 만들고, 그 과정에서 리플랙션이나 예외 등을 포함하는 더 복잡한 로직을 테스트하는 예제. 첫 번째 예보다 훨씬 더 작은 단계로 작업하는 방식을 배우게 될 것이다.
  • 3부. 테스트 주도 개발을 위한 패턴들 - 어떤 테스트를 작성해야 할 것인가, 어떻게 테스트를 할 것인가 등에 대한 패턴과, 예제에서 사용된 디자인 패턴과 리팩토링을 소개한다.

들어가는 글

테스트 주도 개발은 소프트웨어 엔지니어 누구라도 따를 수 있는 기술로, 단순한 설계와 확신을 불어넣는 테스트 슈트를 만들도록 격려한다. 당신이 천재라면 당신에게 이런 법칙은 필요 없다. 또 당신이 멍청이라면 역시 이런 법칙이 도움이 되지 않을 것이다. 그 사이에 존재하는 대다수의 사람들은 다음 두 가지 단순한 법칙을 따름으로써 잠재력을 한껏 발휘할 수 있다.

  • 어떤 코드건 작성하기 전에 실패하는 자동화된 테스트를 작성하라.
  • 중복을 제거하라.

얼마나 정확하게 이것을 지킬지, 이 두 가지 단순한 규칙을 밀고 나갈 수 있는 거리 등이 이 책의 주제다.