Session 3
. 게임에 적용해 보는 TDD. UnitTest

1. TDD란 무엇인가? Test Driven Development. (테스트 주도 개발)

지금까지 소개된 TDD 방법론 관련 서적에서는 JAVA 프로그래밍 환경을 위주로 TDD 개발을 소개하였다. TDD 책을 봐도 2% 부족한 느낌을 지울수 없었는데, NCSOFT 서버 프로그래머 박일님의 KGC 2007 강의를 듣고나서 "아! C++에서도 TDD를 이렇게 쓰면 되는구나!"

라는 생각이 느껴질 정도의 감동이 느껴졌다.

2. TDD의 순환 과정

위와 같이 TDD는 1. 테스트 작성 -> 2. 코드 작성 -> 3. 리펙토링의 과정을 거친다.

일반적으로 하나의 상품을 만들기 위해서 거치는 과정은 다음과 같다.
1. 기획 / 설계 -> 2. 사전 시뮬레이션 -> 3. 개발 / 출시 -> 4. 모니터링 및 사후관리, 성과측정 -> 5. 상품 출시 의 순서와 매우 유사한 점을 발견할 수 있다.

컴퓨터 산업에서도 이미 하드웨어 기반의 제품 생산 라인에서는 위와 같이 TDD와 유사한 제품 생산과정이 이미 도입되어 매우 안정적이고 빠른 제품 생산이 가능하다. 프로그래밍 개발에도 이러한 TDD를 도입하면 테스트를 통해서 안정성이 입증된 모듈을 사용함으로써 유지 / 개발에 드는 비용을 획기적으로 줄일 수 있다.


3. TDD 개발론
1. 간단하고 빠른 테스트 코드 추가
  2. 모든 테스트를 수행하고 실패한 테스트 수정 / 진행
  3. 코드 작성 / 수정
  4. 모든 테스트 통과 성공
  5. 리펙토링을 통한 코드 최적화

TDD에서는 가장 간단하고 빠르게 테스트 코드를 만드는 것이 최우선시 됩니다.
테스트 코드를 만든다는 것은 프로그래머의 사고 과정을 유도하고,
간단한 테스트 코드를 만드는 것으로 프로그래머의 사고 과정을 "simple"하게 정리해 줍니다.

인간의 사고 과정은 복잡 다단하지만, 컴퓨터가 이해하기 위해서는 단순하고 간단한 명제로 바꿔야 하는데 TDD는 이러한 사고 과정을 자연스럽게 숙달, 단련 시켜줍니다.

2번 과정에서 사고과정을 단순화시키는 과정에서 발생하는 실수나 명확하지 않는 테스트 코드만 남게 되므로 프로그래머가 실패한 테스트 코드에 대한 집중력을 높일 수 있습니다.

3번 과정에서 이러한 모든 테스트가 완성된 자체가 코드 작성 / 수정을 마치면 1차적으로 완성된 코드 샘플이 나오게 됩니다.

4번 과정에서 모든 테스트를 통과하게 되면, 이제 프로그래머가 요구사항에 맞는 코드 작성을 모두 완성하게 됩니다.

5번 과정에서는 완성된 코드에 대해서 리펙토링을 진행하게 되는데,
여기서 중요한 점!!
이미 위의 과정에서 테스트 코드가 리펙토링이 안전하게 진행되고 있는지 수시로 확인할 수 있는 안전장치로 작동하기 때문에 프로그래머는 아무런 부담없이 최적화된 코드로 리펙토링 할 수 있습니다.

TDD 개발론을 통해서 프로그래머는 사고 과정의 유연함을 얻는 동시에 안정적인 코드를 얻을 수 있습니다. (TDD를 생활화 하면 두마리 토끼도 잡을 수 있게 되는걸까요? ^^;;)

4. TDD를 활용하기 위한 방법(예제)
TDD를 C++에서 사용하기 위해서 http://unittest-cpp.sourceforge.net/ 에서 UnitTest++ 프로젝트를 다운 받을 수 있다.
비주얼 스튜디오 2003 및 2005에서 사용할 수 있도록 프로젝트 파일 2개가 포함되어 있다.

다행히 비주얼 스튜디오 Express Edition에서도 사용이 가능했다.


위와 같이 UnitTest++.vsnet2005 프로젝트를 통째로 프로젝트 추가하고,
stdafx.h에 UnitTest++.h 헤더 파일을 추가하는 경로명을 적어준다.

테스트 코드를 추가하기 위해서 TestCode 폴더를 추가하고 UnitTestCode.cpp를 추가한다.

#include "stdafx.h"
#include "Calc.h"
 
TEST(ValidCheckSucceeds)
{
  bool const b = true;
  CHECK(b);
}
 
TEST(ValidCheck할까)
{
  CCalc calc;
 
  CHECK_EQUAL( 0, calc.Add( 1, -2 ) );
}

첫번째 "ValidCheckSucceeds" 에서는 CHECK(b)의 값이 참이 되므로 성공으로 넘어간다.
두번째 "ValidCheck할까" 에서는 CCalc::Add(int a, int b)를 테스트하는데,
CHECK_EQUAL( 테스트값, 결과값 ); 테스트 값과 결과값이 같아야 한다.
그러나 여기에서는 "-1"이 정답이므로 테스트를 실패하게 된다.

테스트 코드를 수행하면 다음과 같은 결과를 볼 수 있다.




5. TDD가 만능은 아니다.(단점들)
자칫 TDD를 활용하다 보면 TDD가 전지전능한 신으로 우상화하는 경우가 있다. TDD는 어디까지나 프로그래밍 기법의 하나로 좀더 안정적이고 검증된 프로그래밍을 하기 위한 것이지, TDD 자체가 궁극의 해결책이 될 수는 없다.

한가지 예를 들자면, TDD를 이용해서 소수를 구하는 Class에 대한 테스트 코드를 작성했다고 했을 경우. 테스트 코드가 수용하는 범위의 소수에 대해서만 검증이 가능하다.

 

2      3      5      7     11     13     17     19     23     29
31     37     41     43     47     53     59     61     67     71
73     79     83     89     97    101    103    107    109    113 ...

113을 넘어서는 값부터 일치하지 않는 Class라 하더라도 TestCode를 통과했으니 "이 클래스는 안정적이다." 라고 단언할 수는 없지 않은가...

위의 예에서 유추해 보면 TDD에서 TestCode를 끊임없이 관리하고 리펙토링하지 않으면, Test Code가 제 기능을 발휘하지 못한다는 것을 알 수 있다.

프로그래머는 Test Code를 관리하는 유지 보수 비용을 감당해야 한다.


6. TDD를 통해서 얻을 수 있는 장점들
그렇다고 "TDD를 적용하는데 불편한 점이 많아서 나는 쓰지 않을 테야!" 라고 포기해 버리면,
"과일 깎아 먹기 귀찮아서 과일은 절대 안 먹을꺼야!" 이렇게 불평만 늘어놓는 사람이 되고 만다.

도대체 TDD가 어떤 장점이 있어서 TDD를 써야 한다고 외치는 것인지 살펴보도록 하자.
여기에서는 실무에서 직접 TDD를 사용하신 박일님의 자료를 인용하도록 하겠다.



1. 클라이언트 없이 실행가능 -> (엄청난 시간 단축)
2. 직접 확률을 지정하거나, 코드에서 Loop를 돌릴 수 있다. -> (확률을 고정해서 몇만번의 테스트 가능)
3. 한번 만들어진 테스트는 계속 남는다. -> (코드 재활용 및 안정성 검증 가능)
위와 같이 프로그래머에게 가장 부족한 시간을 확보할 수 있게 해주고,
정말 귀찮은 반복 작업에서 해방시켜주며,
똑같은 테스트를 다시 할 수 있다는 장점이 있다.


이 정도면 대한 독립 만세! 만세 삼창을 해야 하는것 아닌가!!

7. TDD를 다른 사람에게 권유하기 어려운 점
TDD는 장점과 단점을 모두 가지고 있다.
특히나 타인에게 권유하기 어려운 점은 이미 코드짜느라 힘들어 죽겠는데,
뭐하러 힘들게 테스트 코드까지 짊어지고 나아가냐! 라는 반감을 사게 된다.

이럴 때에는 반복작업으로 지친 동료의 업무를 분석해서 TDD를 이용해서 간단하게 검증하는 기반을 만들어주고, "이거 사용하면 편한데..." 라면서 슬쩍 건네주는 센스가 필요하다.
물론 박일님이 저렇게 말씀하신건 아니지만, 저런식으로 타인이 편리하다고 느끼기 전에는 TDD를 도입하는데 많은 어려움이 있다는 것을 반증하는 말씀이 아니었나 싶다.


MFC GUI 환경으로 UnitTest 하기 : 쑥갓님의 UnitTest++용 GuiRunner 0.20업데이트
2007/11/12 20:09 2007/11/12 20:09

글 걸기 주소 : 이 글에는 트랙백을 보낼 수 없습니다

덧글을 달아 주세요

  1. ParkPD 2007/11/13 09:38 고유주소 고치기 답하기

    다음에는 1시간짜리 강연이 아닌, (음주)OST 나 테이블 토의 형식으로 만나서 얘기나눴으면 해요. ㅎㅎ

  2. TTF 2007/11/13 09:41 고유주소 고치기 답하기

    네 덕분에 TDD를 체험하게 되었습니다. 강의 감사드립니다. ^^

  3. w0os 2008/01/14 21:23 고유주소 고치기 답하기

    와... 이런 것도 있구나...
    좋은 거 알았네~ 쌩유~ ^^