인턴으로 근무할 때 공부하며 정리해뒀던 내용을 옮겨온 글이다.
TDD는 여러 개발론 중 하나로 테스트를 우선시하여 개발해 나가는 방식이다. 이러한 TDD는 실패 -> 성공 -> 리팩토링 -> 실패의 cycle을 갖는다..
우선적으로 실패하는 테스트케이스를 작성한다. 여기서는 사실 실패라는 단어의 초점을 맞추기 보다는 테스트케이스를 작성한다는 것의 의의를 둬도 되는 것 같다. 즉 자신이 만들고 싶어 하는 기능의 스펙에 걸맞게, 상황을 가정하여 맞는 답이 나오는지 확인하는 테스트를 만들면 되는 것이다.
검색할 집단 : l = ['a', 'abc', 'bc', 'dd', 'da']
아직 만들지 않은 검색 함수 : searchFunc(data, keyword)
- searchFunc(l, 'a')의 결과가 ['a', 'abc', 'da']로 나오는 지에 대한 테스트를 작성하는 것이다.
물론 아직은 함수가 없기에 통과하지 않을 것이다.
이 부분이 기능 구현의 부분이다. 앞서 실패 단계에서 테스트케이스를 고민해서 작성했다면 내가 구현해야할 기능들과, 그 조건들 또한 쉽게 파악할 수 있다. 이에 맞게 코드를 작성하면 된다.
말 그대로 리팩토링이다. 이전 단계에서 작성한 코드에 중복되는 부분은 없는지, 더 간단히 구현할 수 있는지를 확인하는 파트라고 한다. 이후에는 빼먹은 부분이 없는지 확인해보고, 다음 기능에 대해서 처음부터 반복하면 된다.
TDD 관련 글들을 읽어보면 여러 장점들이 있지만 직접 Test 코드를 작성해보며 느낀 장점 위주로 적는다.
다른 사람이 작성한 코드를 이해하기에 수월하다.
아무 베이스 없이 구현된 코드를 읽으면 코드의 맥락을 파악하기 어려울 때가 있다. 그럴 때 테스트 코드를 먼저 보면, 의도가 무엇인지, 어떤 방식으로 작동하는 것인지에 대한 로직을 파악하기 쉬워서, 협업과정에서 꽤나 좋다고 생각한다.
기능의 분리를 한번 더 생각할 수 있다.
배워나가면서 많이 들었던 이야기는 한번에 한가지 기능만 갖도록 코드를 분할하는 것이 좋다는 이야기였다. 그래야 유지/보수가 쉽고, 수정도 편하기 때문이다. 이러한 측면에서 테스트코드를 작성해보면 내가 만들어야할 기능이 무엇인지 list up하고서, 각각에 맞게 코드를 작성하면 되므로 코드의 분리가 쉬워진다.
이렇듯 장점들이 꽤나 존재하는 방식이지만, 실상 바로 적용하기는 쉽지 않았다. 왜냐하면 테스트 코드를 적는 것은 대다수의 경우에 긍정적인 결과를 가져오지만, 테스트 코드를 '얼마나' 작성해야 하는지는 애매하다. 모든 경우를 테스트할 수 있도록 짜는 것이 당연히 좋겠지만 테스트코드를 작성하는 것도 '리소스'가 필요한 일이고, 동일한 리소스로 다음 태스크를 진행하는 것이 좀 더 효율적일 때도 있기 때문이다.
결국 지금은 실무에서 직접 테스트 코드를 작성해보며 그 장점을 온몸으로 느꼈기에, 시간이 허락하는 선에서는 테스트코드를 최대한 작성하는 것이 좋겠다~~ 라는 생각만 가지고 가려고 한다.