Test Driven Development의 약자로 '테스트 주도 개발' 이라고 합니다.
반복 테스트를 이용한 소프트웨어 방법론으로, 작은 단위의 테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 작업을 반복합니다.
짧은 개발 주기의 반복에 의존하는 개발 프로세스이며, 애자일 방법론 중 하나인 eXtream Programming 의 'Test-First' 개념에 기반을 둔 단순한 설계를 중요시 합니다.
eXtream Programming 이란?
미래에 대한 예측을 하지 않고, 지속적으로 프로토타입을 완성하는 애자일 방법론 중 하나로, 추가 요구사항이 생기더라도, 실시간으로 반영할 수 있습니다.
단위 테스트란?
한 단위만을 테스트하는 것을 말합니다.
TDD 개발 주기로는 3가지 개발 절차가 있습니다.
Red 단계에서는 실패하는 테스트 코드
를 먼저 작성합니다.
Green 단계에서는 테스트 코드를 성공시키기 위한 실제 코드
를 작성합니다.
Blue 단계에서는 중복 코드 제거, 일반화 등의 리팩토링을 수행합니다.
TDD를 개발할 때 실패하는 테스트 코드를 작성할 때
실제 코드를 작성하지 않고 , 실패하는 테스트를 통과할 정도의 최소 실제 코드
를 작성해야 합니다.
이를 통해 불필요한 설계를 피할 수 있으며, 정확한 요구 사항에 집중할 수 있습니다.
보통 개발 방식은 '요구사항 분석 -> 설계 -> 개발 -> 테스트 -> 배포' 의 형태의 개발 주기를 갖는데 이 방식은 소프트웨어 개발을 느리게 하는 단점이 있습니다. 그 이유로는 다음과 같습니다.
자체 버그 검출 능력 저하
또는 소스코드의 품질이 저하
될 수 있습니다.테스트 비용이 증가
할 수 있습니다.이러한 문제가 발생하는 이유는 프로젝트가 초기에 완벽할 수 없기 때문
이며, 보통 고객의 요구사항 또는 디자인의 오류 등 많은 이유로, 재설계하여 점진적으로 완벽한 설계
로 넘어갑니다. 하지만 재설계로 인해 개발자는 코드를 수정하는 과정에 불필요한 코드가 남거나 중복
되는 가능성이 큽니다.
결론적으로 이러한 코드들은 재사용이 어렵고 관리가 어려워져 유지보수를 어렵게 합니다.
작은 부분의 기능 수정에도 모든 부분을 테스트
해야하므로 전체적은 버그를 검출하기 어렵습니다. 따라서 버그 검출 능력이 저하되고, 어디서 버그가 발생했는지 모르기 때문에 잘못된 코드도 고치지 않아 품질 저하를 발생시킵니다.
이렇게 작은 수정에도 모든 기능을 다시 테스트해야 하는 문제가 발생하여 자체 테스트 비용이 증가
합니다.
일반적인 개발 방식과 큰 차이점은 테스트 코드를 작성한 뒤 실제코드를 작성
합니다.
설계 단계에서 프로그래밍 목적을 반드시 정의해야하고, 또 무엇을 테스트해야 할지 미리 테스트 케이스를 작성
해야합니다.
이러한 과정이 진행되면서 자연스럽게 코드의 버그가 줄어들고, 소스코드가 간결해집니다. 또한 테스트 케이스 작성으로 인해 자연스럽게 설계가 개선됨으로 재설계 시간이 절감됩니다.
TDD의 대표적인 Tool은 'JUnit' 이 있습니다.
1 . 디버깅 시간을 단축할 수 있습니다.
이는 유닛 테스팅을 하는 이점입니다.
사용자의 데이터가 잘못 나왔다면 DB의 문제인지, 비즈니스 레이어의 문제인지 UI의 문제인지 모든 레이러들을 디버깅해야 하지만, TDD의 경우 자동화 된 유닛테스팅을 전재하므로 특정 버그를 쉽게 찾아낼 수 있습니다.
2 . 코드가 내 손을 벗어나기 전에 가장 빠르게 피드백을 받을 수 있습니다.
개발 프로세스에서는 보통 '인수 테스트'를 합니다. 이미 배치된 시스템을 대상으로 클라이언트가 의뢰한 소프트웨어가 사용자 관점에서 사용할 수 있는 수준인지 체크하는 과정입니다.
이미 90%이상 완성된 코드를 가지고 테스트하기 때문에, 문제를 발견해도 정확하게 원인이 무엇인지 진단하기 힘듭니다. 하지만 TDD를 사용하면 기능 단위로 테스트
를 진행하기 때문에 코드가 모두 완성되어 프로그래머의 손을 떠나기 전에 피드백을 받는 것이 가능합니다.
3 . 작성한 코드가 가지는 불안정성을 개선하여 생산성을 높일 수 있습니다.
코드가 내손을 떠나 사용자에게 도달하기 전에 문제가 없는지 먼저 진단 받을 수 있습니다.
그러므로 코드가 지닌 불안정성과 불확실성을 지속적으로 해소해줍니다.
4 . 재설계 시간을 단축합니다.
테스트 코드를 먼저 작성하기 때문에 개발자가 무엇을 해야하는지 정의하고 개발을 시작합니다. 또한 테스트 시나리오를 작성하면서 다양한 예외사항을 생각할 수 있습니다.
이는 개발 진행 중 소프트웨어의 전반적인 설계가 변경되는 일을 방지합니다.
5 . 추가 구현이 용이합니다.
개발이 완료된 소프트웨어에 어떤 기능을 추가할 때 우려하는 점이 기존 코드에 어떤 영향
을 미칠지 알지 못합니다.
하지만 TDD의 경우 자동화된 유닛 테스팅을 전제하므로 테스트 기간을 획기적으로 단축시킬 수 있습니다.
1 . 생산성이 저하됩니다.
개발 속도가 느려지는 것이 가장 큰 단점으로, 중간중간 테스트를 하면서 고쳐나가야 하기 때문에 일반적인 개발 방식에 비해 대략 10%~30% 정도의 개발시간이 늘어납니다.
2 . 개발하던 방식을 바꾸어야 합니다.
몸에 체득한 것이 많을 수록 바꾸기 어렵습니다.
3 . 구조에 얽매힌다.
TDD로 프로젝트를 진행하면서 어려운 예외가 생길 수 있는데 그것 때문에 고민하는 순간이 있습니다.
원칙을 깰 수 없고 꼼수는 있는데 그 꼼수를 위해 구조를 바꾸자니 아닌것 같고, 테스트는 말 그대로 테스트일 뿐 실제 코드가 더 중요한 상황인데 테스트 원칙 때문에 쉽게 넘어가지 못하는 그런 경우입니다.