2014년 8월 3일 일요일

TDD는 벌거벗은 임금님의 투명옷인가? (3) - TDD는 UT가 아니다.

TDD는 벌거벗은 임금님의 투명옷인가?




 각종 커뮤니티에서 난리가 나고 업계의 거두가 모여서 현피맞장까지 뜬 TDD를 둘러싼 일련의 소동에 대한 핵심은 다음의 한문장으로 요약될 수 있을것이다.
테스트를 먼저 작성하고 코드를 적는것이 정말로 개발에 그만큼의 가치를 가져다 주는가? 
 그리고 당연하게도 이 물음이 TDD. 즉 테스트 퍼스트 개발을 둘러싼 논쟁의 핵심이 되었어야만 했다.

 TDD의 창시자는 누구이던가? 오늘날의 개발자에게 있어서 십계명이나 다름없는 그 유명한 애자일 선언에 참여한 맴버중에서도 맨 첫머리에 이름을 올린 Kent Beck선생이 아니시던가! 하지만 이러한 '이름의 권위' 앞에서 TDD는 자동화 테스트와 동일시 되어 버려 그 가치를 올바로 평가받을 기회를 잃어버렸던게 아닐까?



 하지만 TDD에만 포커싱을 했으면 좋았을 DHH의 지적질에 애먼 유닛 테스트(이하 UT)가 포함되는 순간, 토론의 목적지는 저 멀리 안드로메다로 재 설정 되어 버리고 만다. Mock오브젝트에만 의존하는 생각없는mindless UT에 대한 반감은 TDD옹호론자라고 해도 공감하는 부분이지만, 엄연히 TDD와 UT에 대한 논쟁은 구분되어 이루어져야 만했었다.

 결론적으로 Martin Flower가 주최한 6회에 걸친 토론중에서 순수하게 TDD자체의 유용성에 대한 토론은 얼마 되지 않았으며, UT에 대한 유용성은 지금와서 이야기 하는것 자체가 무의미할 정도로 업계 전반에서 이미 상식으로 받아들여지고 있는 상황 이므로 아무런 의미가 없었다.

 나름 업계의 존경을 받는 머리 좋은 양반들이 그 귀중한 시간을 내어서 공개적으로 진행한 이벤트 치고는 참으로 어처구니 없는 전개가 아닌가? (그런데 토론을 자세히 보면 능구렁이 같은 Kent Beck이 덩치에 어울리지 않는 애교를 섞어가며 TDD에 대한 논점을 교묘히 흐리는 장면을 자주 볼 수 있다.)

 다시 TDD의 이야기로 돌아와 보자. 
 UT와 뒤섞여 버린 진흙탕 싸움에서 TDD에 관련된 쟁점을만을 분리해 보면 다음의 세가지로 요약된다.
  1. TDD는 오버헤드가 너무 크다  TDD는 커버리지를 중시하지는 않는다고 하면서도 모든 코드에 대한 테스트코드의 작성을 의무화 함으로서 이에 위배되는 모습을 보인다. 결국 개발자는 쓸데 없는 UT작성에 많은 시간을 빼앗길 수 밖에 없다. 하지만, 어느정도 비용이 소요된다 하더라더 테스트 코드가 없는 코드 보다야 훨씬 나을수도 있지 않을까?
  2. TDD가 설계를 망친다  테스트를 먼저 작성해야만 본 코드를 작성하도록 강제하는 룰은 시간에 쫒기는 개발자에게 유닛 테스트를 작성하기 쉬운 설계를 은연중에 강요하게 된다. 이는 결국 유닛테스트를 작성하기 어려운 시스템 횡단적인 기능을 기피하게 만들고 시스템의 설계를 기형적인 모습으로 만들것이다.  
  3. TDD가 테스트를 망친다  1,2와 관련하여 결국 UT만이 너무 강조되는 상황에서는 mock에 의존한 하나마나한 형식적인 테스트로 흐르기 쉬우므로 우리는 이 점을 경계해야만 한다. 또한 UT만큼이나 시스템테스트, 시나리오 테스트도 자동화에 힘을 기울일 수 있어야 할 것이다. 
Tip 요즘 많은 프로젝트들에서 빠르게 실행되는 UT와 시간이 걸리는 DB를 사용하는 결합테스트, 또는 시스템 테스트를 분리해서 구성하고 있다. UT는 커밋시에 개발자 스스로 체크하도록 하고 시간이 걸리는 DB나 그 밖의 미들웨어를 사용하는 테스트는 UT와 함께 젠킨스 등의 CI툴을 이용해 코드 변경시에 실행되도록 해 놓으면 개발자의 시간을 절약하는데 많은 도움이 될 것이다. 아울러 특정 DB에 종속되지 않는 퍼시스턴스라면 UT에도 인메모리 DB를 사용해 테스트 속도를 고속화 할 수 있다.

 TDD가 유용한지 아닌지는 현재 작성하는 프로그램의 성격과 내용, 그리고 작업자의 숙련도에 따라 달라지겠지만 어느정도 오버헤드를 감수해야 함에는 틀림없는 사실이다.

 그리고 여기서 한가지 간과하지 말아야 할 사실은 TDD의 태생이다. TDD는 초기 에자일 프로세스중 하나인 eXtreme Programming과 함께 2000년대 초반에 등장하였는데, 당시엔 오늘과 같이 xUnit테스트가 일반적이지 않았고 대부분의 테스트가 수작업에 의존하던것이 당연하던 시절이다. 이러한 당시 상황속에 UT의 작성을 의무화 하기 위한 하나의 충격요법으로서 XP와 함께 탄생한 TDD를 오늘날에 와서까지 굳이 이를 따라야 할 필요가 있을까?

 필자는 UT가 실행코드와 함께 필수로 받아들여지고 있는 현 시점에서 TDD가 더이상 큰 역할을 하기 어렵다는 DHH의 주장에 동감한다. 이상적인 자동화 테스트 코드는 맹복적인 코드 커버리지보다는 프로그램이 어떻게 움직여야 할지를 기술하는 문서화의 한 형태여야만 하기 때문이다. 반대로 자동화 테스트가 프로그램의 동작을 충분히 설명해 주지 못하고 있다면 추가나 보완이 필요하다고 봐야 한다.

 TDD의 채택여부는 프로젝트의 내용이나 구성원의 취향에 따라 충분히 어느쪽도 선택 가능할 것이다. 하지만, 어떠한 경우라도 자동화 테스트가 없는 개발만큼은 피해야 한다. 이것이야 말로 현대 소프트웨어 개발에 있어서 의심할 여지가 없는 진리이다.