E D R , A S I H C RSS

Test First Programming

메인 코드를 만들기 전에 해당 코드의 의도를 표현해줄 테스트 코드를 먼저 만드는 기법.

어떻게 보면 질답법과도 같다. 프로그래머는 일단 자신이 만들려고 는 부분에 대해 질문을 내리고, TestCase를 먼저 만들어 냄으로서 의도를 표현한다. 이렇게 UnitTest Code를 먼저 만듬으로서 UnitTest FrameWork와 컴파일러에게 내가 본래 만들고자 는 기능과 현재 만들어지고 있는 코드가 는일이 일치는지에 대해 어느정도 디버깅될 정보를 등록해놓는다. 이로서 컴파일러는 언어의 문법에러 검증뿐만 아니라 알고리즘 자체에 대한 디버깅기능을 어느정도 수행해주게 된다.

테스트코드는 프로그래머가 려고 는일, 즉 의도를 담아낸다. 이는 이 프로그램이 어떠한 시나리오로 돌아갈것인가를 먼저 생각해보는 기회를 저절로 제공해준다. Test가 가능한 코드는 run 을 시켰을때 어떤 결과를 낼지를 파악할 수 있는 코드이다. 이 경우 해당 모듈이 완성되었을때가 언제인지 그 목표를 분명게 잡는 역할을 해준다.

테스트코드 자체가 일종의 도큐먼트역할을 기도 한다. 테스트 코드를 만들면서 자신이 려는 일과 문제상황을 구체화 시켜간다.

테스트코드가 완벽할 순 없다. 지만, 테스트코드가 모든 에러를 잡아내지 못한다는 이유로 많은 버그들을 줄일 수 있는 테스트코드를 작성지 않을 이유는 없다.

ExtremeProgramming에서는 UnitTest -> Coding -> Refactoring 이 맞물려 돌아간다. TestFirstProgrammingRefactoring 으로 단순한 디자인이 유도되어진다.

요새는 TestDrivenDevelopment 라고 한다. 단순히 Test 를 먼저 작성는게 아닌, Test 주도 개발인 것이다. TestDrivenDevelopment 는 제 2의 Refactoring 과도 같다고 생각. --1002


참조 사이트 :
테스트 코드 작성에 대해서는 UnitTestPyUnit, CppUnit 를 참조라.

Test Code Refactoring

프로그램이 길어지다보면 Test Code 또한 같이 길어지게 된다. 어느정도 Test Code 가 길어질 경우에는 새 기능에 대한 테스트코드를 작성려고 할 때마다 중복이 일어난다. 이 경우에는 Test Code 를 Refactoring 해야 는데, 이 경우 자칫면 테스트 코드의 의도를 흐트려뜨릴 수 있다. 테스트 코드 자체가 나의 다큐먼트가 되므로, 해당 테스트코드의 의도는 분명게 남도록 Refactoring 을 해야 한다.

Test - Code Cycle

테스트를 작성는 때와 Code 를 작성는 때의 주기가 길어질수록 힘들다. 주기가 너무 길어졌다고 생각되면 다음을 명심라.

Test Code Approach

Test Driven 에 대한 접근 방법에는 End-To-End (BlackBoxTesting) 식의 접근 방법과 WhiteBoxTesting 의 접근방법이 있을 수 있겠다.

전자의 경우는 일종의 '부분결과 - 부분결과' 를 이어나가면서 최종목표로 접근는 방법이다. 이는 어떻게 보면 Functional Approach 와 유사다. (Context Diagram 을 기준으로 계속 Divide & Conquer 해 나가면서 가장 작은 모듈들을 추출해내고, 그 모듈들을 나씩 정복해나가는 방법)

후자의 경우는 해당 코드의 구조를 테스트해나가는 방법으로, 해당 코드의 진행이 의도한 상황에 맞게 진행되어가는지를 체크해나가는 방법이다. 이는 MockObjects 를 이용여 접근할 수 있다. 즉, 해당 테스트려는 모듈을 MockObject로 구현고, 호출되기 원는 함수들이 제대로 호출되었는지를 (MockObjects 의 mockobject.py 에 있는 ExpectationCounter 등의 이용) 확인거나 해당 데이터의 추가 & 삭제관련 함수들이 제대로 호출되었는지를 확인는 방법 (ExpectationList, Set, Map 등의 이용) 등으로서 접근해 나갈 수 있다.

Test - Code 주기가 길다고 생각되거나, 테스트 가능한 경우에 대한 아이디어가 떠오르지 않은 경우, 접근 방법을 다르게 가져보는 것도 나의 방법이 될 수 있겠다.

시나리오의 이용

Test Code 를 작성진 않았지만, 이런 경험은 있었다. PairProgramming는 중 파트너에게
'이번에는 Socket Class 를 만들 차례야. 시작해볼까'

파트너가 먼저 코드를 잡긴 했는데, 코드가 좀처럼 진행이 되지 않았다. 문제가 뭘까 고민다가 다음과 같이 접근해봤다.
'지금 저쪽에는 에코서버가 있어. 지금 만들건 클라이언트고, 지금 만들 클래스로 write 를 면 저기 띄어놓은 에코서버에 내가 입력한 메세지가 그대로 표시될거야' 즉, 완성되었을 때의 결과를 미리 그려보는 것이다.

아까보다 훨씬 수월게 진행되었고, 그 결과를 눈으로 확인했고, 결과를 눈으로 확인한뒤 '완료' 했다. TFP 라면 이를 코드로 작성여 자동화 할 것이다. 자동화된 테스트는 앞으로의 추후 모듈 수정시에도 앞에서 내가 원는 기능들이 여전히 작동함을 보장해준다.

Random Generator

Random 은 우리가 예측할 수 없는 값이다. 이를 처음부터 테스트를 려고 는 것은 좋은 접근이 되지 못한다. 이 경우에는 Random Generator 를 MockObjects 로 구현여 예측 가능한 Random 값이 나오도록 한 뒤, 테스트를 할 수 있겠다.

Server - Client

이 경우에도 MockObjects 를 이용할 수 있다. 기본적으로 XP에서의 테스트는 자동화된 테스트, 즉 테스트가 코드화 된 것이다. 처음 바로 접근이 힘들다면 Mock Server / Mock Client 를 만들어서 테스트 할 수 있겠다. 즉, 해당 상황에 대해 이미 내장되어 있는 값을 리턴해주는 서버나 클라이언트를 만드는 것이다. (이는 TestFirstProgramming 에서보단 AcceptanceTest 에 넣는게 더 맞을 듯 다. XP 에서는 UnitTestAcceptanceTest 둘 다 이용한다.)

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:28:11
Processing time 0.0382 sec