TDD는 매우 짧은 개발 사이클의 반복에 의존하는 소프트웨어 개발 프로세스 중 하나이다. 우선 개발자는 요구되는 새로운 기능에 대한 자동화된 테스트 케이스를 작성하고 해당 테스트를 통과하는 가장 간단한 코드를 작성한다. 우선적으로 테스트를 통과 시킨 후에 코드를 리팩토링하는 방법이다. TDD 이름 그대로 테스트가 개발을 주도하는 개발 방식이다.
테스트 주도형 개발에서는 새로운 기능을 추가하기 전에 테스트를 먼저 작성해야 한다. 테스트를 작성하기 위해서 개발자는 해당 기능의 요구사항과 명세를 정확하게 알고 있어야 한다. 이는 User Case나 User Story 등으로 이해할 수 있고, 이는 개발자가 코드를 작성하기 전에 보다 요구사항에 집중할 수 있도록 도와준다. 이는 정말 중요한 부분이고 테스트 주도형 개발이 주는 이점이라고 할 수 있다.
새로운 기능을 추가하면 잘 동작하던 기능이 제대로 동작하지 않는 경우가 발생할 수 있다. 개발자가 이를 모르고 지나친다면 나중에 큰 문제로 발전할 수 있다. 테스트 코드를 작성하면 이러한 상황을 방지할 수 있다. 새로운 기능을 추가할 때마다 테스트 코드를 작성하여 새로운 기능이 제대로 동작함과 동시에 기존의 기능들이 잘 동작하는지 테스트를 통해 확인할 수 있게 된다.
좋은 코드를 작성하는 것은 쉽지 않은 일이다. 좋은 코드를 작성하기 위해서는 많은 요소들을 모두 신경써야 하기 때문이다. 우선 코드의 가독성을 위해 coding convention을 맞추고, 네이밍 규칙을 적용하여 메소드명, 변수명, 클래스명에 일관성을 부여해야 하고, 앞으로의 확장성 또한 고려해야 한다. 이와 동시에 비즈니스 로직에 대한 고려도 반드시 필요하며 예외처리 또한 적용해야 한다. 코드량이 많지 않을 경우에는 이 요소들을 모두 챙기며 코드를 작성할 수 있지만 버그들을 디버깅하는 과정에서 코드가 더럽혀지기 쉽다.
이러한 이유로 코드가 방대해지면 리팩토링을 진행한다. 이때 테스트 주도 개발을 통해 개발을 해왔다면, 테스트 코드가 그 중심을 잡아줄 수 있게 된다. 하나의 큰 함수를 여러개의 작은 함수로 나누는 과정에서 함수가 오작동하는 경우가 발생할 수 있지만 간단히 테스트를 돌려봄으로써 이를 확인하고 처리하며 리팩토링을 보다 편하게 할 수 있게 된다. 결과적으로 리팩토링 속도도 빨라지고 코드의 퀄리티도 그만큼 향상된다. 여기서 말하는 코드 퀄리티는 보다 객체지향적이고, 확장 가능이 용이하고, 재설계의 시간을 단축시킬 수 있고, 디버깅 시간이 단축되는 코드를 말하며 이러한 코드가 TDD와 함께 탄생할 수 있다.
TDD 방식이 아니더라도 코드를 짜는 중간 중간에 제대로 동작하는지 확인을 해야한다. TDD는 이 때 테스트와 테스트에 대한 문서를 자동으로 해주면서 코드 작성에 도움을 주게 된다.
테스트 주도형 개발을 채택할 경우 코드량이 분명히 늘어난다. 로직, 코드 디자인 외에 테스트 코드까지 작성해야 하기 때문에 코드 퀄리티는 챙길 수 있지만 빠른 시간 안에 코드를 작성해야 하는 경우라면 테스트 주도형 개발은 적절치 않다.
어떤 부분을 테스트 해야 하는지, 어떻게 테스트를 해야 하는지, 여러 테스트 프레임워크 중 어떤 것이 현재 서비스와 적합한지 등 여러 부분들에 대한 학습이 필요하고 익숙해지는데도 시간이 소요된다. 또한 팀원 중 소수만 알아선 안되고 팀원 모두가 익숙해져 있어야 테스트 코드가 빛을 발하게 된다. 즉, 테스트 코드는 진입 장벽이 높고, 이는 테스트 주도형 개발 채택에 걸림돌이 된다.
세상에는 다양한 개발자들이 존재하고 생각치도 못한 예외가 존재한다. 만약 테스트 코드를 작성하다가 어려움이 생긴다면 이 때문에 코드의 구조를 바꾸는 등 개발의 중심이 실제 코드에서 테스트 코드로 넘어가 버리기도 한다. 실제 코드보다 방대해진 코드를 관리하는 것 또한 버거운 일이다.
결론은 모든 코드에 대해 테스트 코드를 작성할 수 없으며 작성할 필요도 없다. 또한 테스트 코드를 작성한다고 해서 버그가 발생하지 않는 것도 아니다. TDD는 100% converage와 100% 무결성을 보장하지 않는다.