TDD란?

TDD는 테스트 중심 개발(Test Driven Development)의 약자로, 개발 과정에서 테스트를 먼저 작성하는 방법론입니다. 짧은 개발 주기(보통 몇 분에서 몇 시간)의 반복에 의존하며, 동작하는 코드를 작성하기 이전에 테스트를 먼저 작성하고, 그 테스트를 통과하는 코드를 작성함으로써 테스트된 동작하는 코드를 얻는 방식으로 진행되죠.

출처:  코드 품질을 높여주는 테스트 주도 개발 알아보기


TDD는 위 그림에 나와 있듯 세 가지 단계를 한 사이클로 돌게 됩니다.

 

RED 단계에서는 '실패하는 테스트 코드’를 먼저 작성합니다. '실패하는 테스트 코드'란 최종적으로 코드가 수행해야될 동작을 의미합니다. 아직 동작하는 코드가 없으니 해당 테스트는 실패할 수 밖에 없습니다. 한 사이클의 목표는 이 테스트가 통과되도록 하는 것이죠.

 

Green 단계에서는 테스트 코드를 성공시키기 위한 실제 코드를 작성합니다. 가장 우선이 되는 목표는 테스트를 통과하는 코드를 작성하는 것입니다. 어떻게든 테스트를 통과하는 코드를 빠르게 작성하는 것이 중요하죠.

 

Yellow 단계에서는 중복 코드 제거, 일반화 등의 리팩토링을 수행합니다. 이제는 테스트를 통과하는 코드를 얻었고 코드가 원하는 대로 동작하고 있으니 이 코드를 '깔끔하게' 만들 차례입니다. 테스트의 보호 아래에서 효율적이고 가독성 좋은 코드가 될 때까지 코드를 리팩토링합니다.

 

이 사이클은 마치 퍼즐 그림을 먼저 완성한 후, 조각 하나하나를 맞춰나가는 것과 같죠. 테스트 코드를 통해 필요한 기능을 명확하게 정의하고, 최소한의 코드로 기능을 구현하게 되니 불필요한 설계나 버그를 줄이는 것이고 명확한 요구사항에 집중하는 것이 TDD의 목적입니다.

 

이때 하나의 테스트는 가장 작은 것 하나만을 테스트해야 합니다. 하나의 기능, 또는 하나의 메서드 수준을 테스트하며, 코드 변경 시 발생하는 문제를 더 빠르게 발견하고, 코드 간의 결합도를 낮출 수 있습니다. 더 낮은 결합도를 가진 코드는 많은 장점이 있고 테스트 자체도 쉬워집니다. 그리고 하나의 기능만을 테스트하는 코드는 문서화도 쉽습니다. 의존성이 낮기 때문에 다른 코드를 보지 않고도 테스트를 이해할 수 있어 문서화에도 용이합니다.

TDD로 얻을 수 있는 것

잘 작동하는 깔끔한 코드

TDD는 테스트를 먼저 작성하기 때문에, 개발자는 코드를 구현하기 전에 무엇을 만들어야 하는지 명확하게 파악할 수 있습니다. 이는 개발 과정에서 발생할 수 있는 기능 누락이나 불필요한 기능을 가진 복잡한 코드를 만들 가능성을 줄여줍니다. 또한 TDD는 각 기능을 독립적으로 테스트하기 위해 작은 단위로 코드를 분리하도록 합니다. 이는 코드 간의 결합도를 낮추어, 코드의 유지 관리 및 확장성을 향상시킵니다. 코드 간의 의존성이 낮아지면 버그 발생 시에도 영향 범위를 최소화할 수 있기 때문입니다. 테스트를 통과하기 위해 코드를 효율적으로 구성해야 하기 때문에, 결과적으로 요구에 맞게 잘 작동하는 깔끔한 코드를 만들 수 있습니다.

개발 시간의 단축

TDD는 처음에는 테스트 작성 과정으로 인해 개발 시간이 증가할 수 있습니다. 하지만, 장기적으로는 코드 설계 개선, 버그 감소, 디버깅 시간 단축 등의 효과를 통해 전체 개발 시간을 단축할 수 있습니다. 테스트를 통해 코드를 지속적으로 검증하기 때문에, 개발 과정에서 발생하는 오류를 미리 발견하고 빠르게 수정할 수 있도록 도와줍니다.

 

또한, TDD는 "안전한" 환경에서 리팩토링을 할 수 있도록 도와줍니다. 잘 작성된 테스트는 코드를 수정하다가 원치 않게 코드의 동작이 바뀌지 않도록 막는 든든한 보호막이 되어줍니다. 이는 리팩토링을 용이하게 하여 장기적인 개발 효율성을 높여 줍니다.

변화에 대한 빠른 적응

요구 사항은 쉽게 변경될 수 있습니다. 그래서 변화에 빠르게 맞추어야 하죠. 테스트 코드는 마치 설계도와 같습니다. 요구 사항이 변경 되었을 때 테스트 코드만 바꾸면 요구 사항의 변화가 코드 전체에 미치는 영향을 파악하고 문제를 해결할 수 있습니다.

재미와 용기

TDD는 테스트를 통해 목표를 명확하게 설정하고 단계별로 달성해나가는 과정입니다. 이는 퍼즐을 푸는 듯한 재미를 느끼게 하고, 테스트 통과를 통해 올바른 방향으로 나아가고 있다는 확신을 얻을 수 있습니다. 또한, 테스트를 통한 지속적인 검증은 개발자에게 용기를 주고, 다음 단계로 나아갈 수 있도록 격려합니다.

더 좋은 문서

테스트는 코드의 기능을 검증하고 버그를 발견하는 데 필수적인 역할을 합니다. 다시 말해, 코드가 수행해야 될 역할과 기능이 무엇인지 테스트 자체에 모두 들어있다는 것입니다. 테스트는 잘못된 의사소통으로 인한 오해를 만들 가능성을 줄여주는 문서가 되기도 합니다. 팀 내에서 코드의 역할과 기능이 무엇인지에 대해서 같은 시각을 가질 수 있도록 돕기 때문입니다.

 

향후 요구 사항이 변경되면 테스트 코드 부분이 먼저 변경되어야 하므로, 항상 최종 정보를 제공하는 문서로 관리될 수도 있습니다. 테스트 자체가 곧 시스템이 어떻게 동작해야 하는지에 대한 이야기이기 때문에 좋은 테스트는 곧 좋은 문서가 됩니다.

 

TDD에 대한 개인적인 생각

TDD를 사용하면서 얻을 수 있는 가장 좋은 이점은 작성하려는 코드의 목적을 명확히 하는 것이라고 생각합니다. 이를 통해 필요한 기능만을 가진 코드를 작성하여 시간낭비를 줄일 수 있습니다. 다른 장점, 예를 들어 문서화나 보호된 환경에서의 리팩토링 등은 TDD의 부가적인 이점이라고 생각합니다. 꼭 테스트 코드를 작성하지 않더라도 TDD의 관점으로 개발을 한다면 코드의 목적을 명확히 하는 개발 습관을 들일 수 있을 것이라고 생각합니다. 모든 코드를 테스트 하는 것이 불합리한 것은 아니겠지만 실제 테스트 코드의 작성은 디버깅, 리팩토링 그리고 문서화에 실질적인 도움이 필요한 경우에 작성하는 것이 좋겠다는 생각이 듭니다.

참고 자료

samsung SDS, 코드 품질을 높여주는 테스트 주도 개발 알아보기
카카오페이 기술 블로그, 실전에서 TDD하기
와디즈 기술 블로그, 프론트엔드 개발자의 TDD 적응하기
요즘 IT, TDD, 실패하는 테스트부터 작성해 얻는 것 5가지

[번역] TDD에 대한 큰 오해

+ Recent posts