Test First Programming UserPreferences
 
Help Info Print View Search Diffs Edit
 인덱스   찾기   Freeboard   Subjectless   Images   최근글 

실제 프로그램을 하기 전에 테스트를 먼저하라는 XP의 중요 원칙 중 하나.

장점:

DIP의 [WWW]5장UnitTesting 설명이 있긴 한데, 아주 심각한 문제(실행코드와 테스트코드가 함께 점진적으로 성장해 나가지 않고 테스트코드를 먼저 완성하고 나서 하나하나 통과해 나가는 것은 XP가 BUFD라고 부르며 경계하는 것 중 하나이다)가 있는 설명이다. XP와 TFP에 대한 이해가 없는 사람은 주의를 요한다. PyUnit?의 사용법을 익히기에는 괜찮다.


먼저 테스트 프로그램을 작성하고 나서, 이 테스트 프로그램을 통과하는 프로그램을 만든다. ProgrammingByIntention?이 가능한 것이다.

예를 들어, 1부터 N까지의 합을 구하는 프로그램을 작성한다고 하면, 대부분의 프로그래머들은 구체적 로직부터 생각하는 BottomUp?방식으로 접근할 것이다. 하지만 이런 경우, 멍하니 먼 산만 바라보며 뭘 먼저 해야할지 감이 오지 않는 경우도 많고, 언제 이 프로그램이 완성되는지도 알기 힘들고, 더구나 프로그램 작성 중간에 코드를 고치는 것을 꺼리게 된다.

하지만, ProgrammingByIntention?TestFirstProgramming에서는 먼저 "의도"(intention)가 드러나도록 한다. 따라서 훌륭한 디자인도 덤으로 얻는다.

TFP와 PBI를 하는 프로그래머는 먼저 다음의 코드를 작성한다:

... 
out=1+2+3+4+5+6+7+8+9+10 
self.assertEqual(out,sumFromOne(10)) 
... 

이 때 이미 프로그래머는, 가장 분명하고 단순한 코딩을 하면서 동시에 자신이 작성할 프로그램의 인터페이스를 디자인한 것이다. 목표가 만들어 졌으면 이 목표를 완수하는 프로그램을 만들면 된다.

사실 이 테스트 코드를 먼저 작성하고 바로 테스트 코드를 실행한다. 그러면 당연히 sumFromOne이라는 이름이 정의되어 있지 않다는 에러가 나온다. 이 때 바로, 컴퓨터가 요구하는 것을 들어주면 된다. 즉, sumFromOne이라는 이름을 정의한다.

def sumFromOne(upTo): 
    pass 

여기까지만 작성하고 다시 테스트 코드를 돌린다. 그러면 이번에는 아까의 이름이 정의되어 있지 않다는 에러는 사라지고 이번에는 1부터 10까지의 합이 None값(sumFromOne의 리턴값)과 다르다는 "실패"(failure) 메세지가 나온다.

그럼, 이제는 다시 컴퓨터가 요구하는, 두 값을 동일하게 해주는 코드를 작성하면 된다. (언제나 실패하는 부분이 한 군데 임에 주의한다. 새로운 기능을 추가할 때도, 테스트 코드에 해당 기능 관련 테스팅을 먼저 추가하고, 다음 그 코드를 패스하는 실행 코드를 작성하는데, 언제나 한 걸음 씩 나가야 한다. 동시에 두개 이상의 기능을 추가하고 테스팅이 실패하면 어느 것이 문제였는지 찾아내는 데에 시간이 허비된다)

def sumFromOne(upTo): 
    sum=0 
    for i in range(1,upTo+1): 
        sum+=i 
    return sum 

이제 테스트 코드를 돌리면 패스하는 것을 확인할 수 있다.

이로써 우리는 "지속적으로 컴퓨터가 요구하는 한가지"만 해결해 주면서 전체문제를 점진적으로 해결했다. 또 처음 출발 때 가장 분명하게 "의도"를 드러냈기 때문에 인터페이스 디자인(여기서는 함수 이름, 인자 내용 등) 등이 깔끔하고, 로직도 분명하다.

또 100% 패스하는 테스트 코드가 갖춰져 있기 때문에 과감히 실행 코드를 변경/개선할 수 있다. 만약 한 부분을 개선했는데(small step is important!) 기존에 패스하던 테스트 몇 개가 실패를 한다면 방금 고친 부분이 문제를 야기한 것이므로 그 부분을 다시 분석한다.


실생활에의 적용

무슨 일이건 해야할 일이, 풀어야할 문제 상황이 존재한다면 우선 그 문제가 해결된 상황을 상정한다. 그리고 그 상황에서 해결이 되었는지 안되었는지를 확인할 수 있는 방법을 생각한다. (이를 TopDown
? 방식이라고도 하고, 미로의 목적지에서 반대로 거슬러 내려오는 방법이라고도 볼 수 있다.) 일종의 테스트 방법을 만드는 것이다.

이제는 좀전의 테스트를 100% 통과할 수 있는 방법을 생각한다. 이것이 너무 복잡하다면, 다시 작은 단위의 테스트를 만들고, 이 테스트를 통과할 방법을 생각한다. 주의점은 한번에 꼭 하나의 테스트만 통과할 고민을 해야 한다.

예를 들어, 부산에 가야한다면, 자신이 부산이 도착했다는 것을 확인할 수 있는 간단한 테스트를 생각한다. "부산역"에서 그 글자를 읽는 것처럼 분명하고 단순한 것일수록 좋다. 이제는 부산역 글자를 읽어야 하는 테스트를 통과할 방법을 생각한다. 간단하게는 서울역에서 기차를 타고 부산역으로 가는 것이다. 그러면 또 다시, 서울역에서 기차를 탔다는 것을 확인할 테스트를 생각하고, 또 이 테스트를 통과할 방법을 생각해 낸다.

복잡한 일일수록 이 문제해결법은 효력를 발휘한다.


프로그래밍분류


PythonPowered EditText of this page (last modified 2003-04-16 10:42:51)
FindPage by browsing, searching, or an index
Or try one of these actions: DeletePage, DeleteUploadedFile, LikePages, SpellCheck, UploadFile