테스트 주도 개발, 켄트 벡

2018-09-06·programming

처음에는 자동화된 테스트를 작성하면 TDD(Test Driven Development)인가 싶었다. 더 주워 듣고는 테스트 ‘먼저’ 작성하면 테스트 주도 개발인가 싶었다. 이렇게 TDD라는 단어만 머리속에 멤돌고 이해하고 실천하려는 노력은 별로 없었다. 막연하게 ‘효율 따져가며 테스트 짜면 좋겠지 뭐’ 정도의 결론을 갖고 있었다. 그러나 이 책을 통해 예제를 살피며 여러 원칙과 패턴 그리고 가치까지 살펴보니 생각보다 재밌었다.

‘테스트 작성 -> 실패 -> 성공 -> 리팩터링 ’의 사이클을 의도적으로 실천하면서 꽤나 어색해서 놀랬다. 코드가 사용되는 관점에서 먼저 생각하며 테스트를 작성하고, 가짜 구현을 하더라도 테스트를 통과하는 최소한의 구현을 하고, 다시 리팩터링 하는 일련의 피드백 주기를 짧게 가져갔다. 이런 구현에 대한 짧은 피드백 주기의 반복 속에서 좀 더 꼼꼼하게 여러 상황들을 고려하며 코드를 작성할 수 있었다.

하지만 작성한 모든 테스트들이 위와 같이 즐거운 느낌을 주는 건 분명 아니었다. 하염없이 모킹을 하며 도대체 뭘 테스트하고 있나 싶기도 했고, 극단적으로 코드를 다시 작성하고 싶은 마음도 들었다. 회사 동료들과 이 책을 조금씩 읽어가며 테스트 케이스를 모아 서로 공유하는 시간을 가졌는데, Mocking/Fixture 에 대한 고민도 하고 복잡한 비즈니스 로직에서 높은 응집도와 낮은 결합도를 지향하면서 테스트를 작성해나가는 어려움도 토로했다.

이 책을 통해 TDD 에 입문? 했다. 코드 품질을 올리기 위한 실천적인 방법이라는 인식 변화부터, 코드를 실행하며 검증해보는 실용성까지 어느 정도 TDD를 긍정하게 되었다. 물론 아직까지 미숙하고 경험도 적어 테스트 작성 비용이 많이 드는 건 사실이다. 아무쪼록 이번 계기를 통해 TDD를 조금 더 실천해봐야 겠다는 생각이 든다. 의도적인 수련을 해야겠다.

cf) 장고 튜토리얼을 보던 중 Why you need to create tests 라는 섹션을 읽게되었다. 명료한 논리라고 생각한다.

갈무리

  • 23p 순서가 다음과 같이 결정된다.

      1. 빨강 - 실패하는 작은 테스트를 작성한다. 처음에는 컴프일조차 되지 않을 수 있다
      1. 초록 - 빨리 테스트가 통과하게끔 만든다. 이를 위해 어떤 죄악을 저질러도 좋다.
      1. 리팩토링 - 일단 테스트를 통과하게만 하는 와중에 생겨난 모든 중복을 제거한다.
  • 43p 테스트를 작성할 때는 오퍼레이션의 완벽한 인터페이스에 대해 상상해보는 것이 좋다.

  • 67p 우리는 완벽함을 위해 노력하지는 않는다. 모든 것을 두 번 말함으로써(코드와 테스트로 한 번씩) 자신감을 가지고 전진할 수 있을 만큼만 결함의 정도를 낮추기를 희망할 뿐이다.

  • 85p 더 많은 동기가 있기 전에는 더 많은 설계를 도입하지 않기로 했다.

  • 208p 발 디딜 곳이 확실해지기 전엔 결코 발을 떼어 전진하지 말자는 것이다. 프로그래밍하기 위해 자리에 앉았을 때, 우리가 성취하고자 하는 것은 무엇인가?

  • 210p 스트레스를 받을 수록 테스트가 충분치 못할 가능성이 높아진다. 테스트를 충분히 하지 못했다고 생각하면 스트레스는 더 커진다. 양성 피드백 고리다. 이번에도 역시 이 고리에서 빠져나갈 방법이 필요하다. 테스트를 먼저 해야 한다는 규칙을 도입해보면 어떨까? 그렇게 하면 영향도를 뒤집을 수 있고 효과적인 주기를 만들어내게 된다. 위쪽에 있는 ‘테스트 먼저’가 아래쪽에 있는 스트레스에 음성적으로 연결된다. 테스트를 먼저 하면 스트레스가 줄고, 따라서 테스트를 더 많이 하게 된다. 하지만 스트레스를 유발하는 다른 원인들임 많기 때문에 테스트는 또다른 효과적인 주기의 영향도 함께 받아야 할 것이다.

  • 210p 코드를 작성한 이후에는 테스트를 많들지 않을것이다. 프로그래머로서 목표는 기능이 실행되도록 만드는 것이다. 또 한편으로는 프로그램의 설계에 대해 생각해볼 시간도 필요하고 작업 범위를 조절할 방법도 필요할 것이다.

  • 244p 가짜로 구현하기는 등산할때 피톤을 머리위에 박아주는것과 비슷하다. 아직 그곳에 도달하지는 못했지만 그곳에 일단 도달하면 안전할 것임을 알 수있다.

  • 297p 나는 복잡한 코드를 이해하고자 할 때 메서드 추출하기를 사용한다. “여기 이부분이 어떤 일을 수행하는데... 이걸 뭐라고 부르면 좋을까?”

  • 318p 확실히 하지 말아야 할 일이 있는데, 그것은 코드 전체를 위한 테스트를 한꺼번에 다 만들고, 코드 전체를 한번에 리팩토링하는 일이다. 이런 작업은 몇 달이나 걸릴 텐데, 그 몇 달 동안 아무런 새로운 기능 추가도 구현하지 못할 것이다. 수입 없는 지출은 일반적으로 지속 가능한 프로세스가 아니다.

  • 319p 모든 프로그래밍 방법은 명시적이건 암묵적이건 간에 어떤 가치 체계를 내포한다. TDD 역시 다르지 않다. 만약 당신이 어느 정도는 작동하는 코드를 왕창 입력해 넣는 것에 행복해 하고, 그 결과를 두 번 다시 쳐다보지 않는 것에 행복해 한다면, TDD 는 당신을 위한 것이 아니다. TDD는 더 나은 코드를 작성한다면 좀더 성공할 것이라는, 매력적일 정도로 나이브하며 해커적인 가정에 근거한다. TDD는 더 깔끔한 설계를 할 수 있도록, 그리고 더 많은 것에 배워감에 따라 설계를 더 개선할 수 있도록, 적절한 때 적절한 문제에 집중할 수 있도록 도와준다.