테스트 주도 개발 방법론 (tdd)
TDD (Test Driven Development, 테스트 주도 개발)
매우 짧은 사이클을 반복하여 소프트웨어를 개발하는 프로세스 중 하나로, 테스트 케이스 작성 -> 구현 -> 리팩토링의 짧은 과정을 반복하는 개발론.
핵심은 반복 테스트로, 작은 단위의 테스트 케이스를 자주 반복하는 것이 핵심이다.
애자일 방법론중 하나인 Extream Programming의 Test-First 개념에 기반을 둔 설계를 가장 중요시 함.

R. 실패 (Red)
TDD의 시작은 우선 실패하는 Test Case를 찾는 것 에서 시작된다.
이 Test Case란 프로젝트 전체 기능에 대한 테스트가 아닌, 지금 당장 구현할 기능 하나에 대한 Test Case가 필요하다.
G. 성공 (Green)
두 번째 단계인 성공에서는, 실패과정에서 찾은 실패하는 Test Case를 성공시키는 코드를 작성하는 단계이다.
R. 리팩토링 (Refactor)
마지막 단계인 리팩토링은, 우리가 구현한 코드 내에 중복되는 코드, 개선이 필요한 코드 등에 대한 재작성을 의미한다.
이 단계가 끝나면 다음 기능 개발을 위한 실패하는 Test Case를 찾고, 1번째 단계부터 진행한다.
TDD 예시
- 3차원 좌표계에서 두 지점 사이 거리를 재는 프로그램
- 두 지점 사이 x좌표 간 거리를 잴 수 있는 프로그램을 만들기를 우선 목표로 정한다.
(0), (5) -> 5를 목표로 설정
- 후에 테스트 할 예제를 설계한다.
(0), (5)를 입력 시5를 반환하는 테스트 코드 설계
- 1에서 설정한 만들고자 하는 코드 구현.
- 테스트 코드로 3에서 구현한 코드를 실행.
- 통과했다면, 새로운 테스트를 진행한다.
(0,0), (5,5) -> 5*sqrt(2)를 목표로, 코드를 확장한다.
- 위의 작업을 반복 수행하여, 3차원까지 확장한다.
- 두 지점 사이 x좌표 간 거리를 잴 수 있는 프로그램을 만들기를 우선 목표로 정한다.
TDD와 일반 개발의 차이점
TDD의 의의로는 개발 과정에서 테스트를 우선 작성하고, 그걸 통과하는 코드를 만드는 과정을 반복하며, 제대로 동작하는지 여부에 대한 피드백을 적극적으로 수용 및 개선해나갈 수 있다.
기존 개발 방식인 요구사항 분석 - 설계 - 개발 - 테스트 순으로 개발 시, 개발을 느리게 하는 아래 잠재적 위협이 존재하게 된다.
- 고객의 요구사항이 명확하지 않거나 변화.
- 자체 버그 검출 능력 저하 또는 소스코드의 품질 저하 야기.
- 자체 테스트 비용 증가.
이러한 위협들은 어떤 프로젝트라도 초기 설계의 미흡함에서 100% 벗어나기 힘들 기 때문에 발생한다. 고객의 요구사항은 언제든 변경될 수 있고, 외부/내부 조건들에 의한 재설계를 통해 점차 이상적인 형태로 프로젝트는 발전해나간다.
이 과정에서 재설계 중, 새 코드를 추가/수정/삭제 하는 과정에서, 불필요한 코드가 남거나 중복되는 작업을 수행하는 코드가 남을 가능성이 크다. 이런 코드들은 재사용이 까다롭고, 사후 관리가 어려워져, 프로젝트 전체의 유지보수를 어렵게 만드는 요인으로 작용한다.
이 뿐만 아니라 코드의 사소한 수정에도 프로젝트의 모든 부분을 테스트해야하므로, 테스트에 소요되는 자원이 늘어나고, 이는 곧 프로젝트 전체의 버그 검출을 까다롭게 만든다.
일반적인 개발에서는 코딩이 끝난 후 테스트를 한번에 진행하게 되는데, 이 순서를 테스트를 만든 후 코딩으로 바꾸는 것이 바로 TDD를 프로젝트에 적용하는 핵심 방법론이다.
TDD의 장점
- 객체지향적 코드 생산
- TDD의 특성 상 코드의 재사용성을 보장한다. TDD를 통한 소프트웨어 개발 시 기능 별로 철저하게 모듈화가 이루어지기에 종속성과 의존성이 낮다. 이후, 필요에 따른 모듈 추가 및 제거가 상대적으로 자유롭다.
- 리팩토링 시간 단축
- 테스트 코드를 미리 작성하기에, 개발자가 지금 어떤 기능을 개발하는지 분명하다. 테스트 시나리오를 작성하며 다양한 예외사항도 고려 가능하다.
- 디버깅 시간 단축
- 유닛 테스트로부터 오는 이점으로, TDD를 통해 짜여진 테스트를 전제로 개발하므로 특정 버그 검출이 용이하다.
- 추가 구현에 용이함
- 개발이 완료된 소프트웨어에 추가 기능을 구현할 때 가장 문제되는 부분 중 하나는, 새로 만든 코드가 기존 코드에 생각지 못한 영향을 끼칠 수 있다는 점이다. 하지만 TDD의 경우 자동화 된 유닛 테스팅을 진행하므로, 테스트 기간 단축에 용이하다.
위와 같은 장점에도 불구하고, 왜 이 개발 프로세스를 따르는 개발자는 찾기 힘들까?
TDD 적용 의 단점
- 생산성의 저하
- 처음부터 두 종류의 코드(테스트, 기능)를 구현해야하고, 테스트를 통해 고쳐 나가야 한다.
- SI 프로젝트에서는 소프트웨어의 품질보다 기한 준수가 더 중요한 경우가 많기에, TDD를 채용하기 적합하지 않다고 판단하는 경우가 많다.
- 새로운 개발 방식 학습 필요
- 이미 체득한 기술(learn)을 잊어버리고(unlearn), 새로운 기술을 다시 익히는(relearn) 과정이 필수적이다.
- 이로 인해 개발 경험이 작은 개발자에게 TDD를 적용하는 것은 상대적으로 수월하다.
TDD를 용이하게 만드는 팁
- 본인의 작업 방식을 스스로 발전시켜야 함.
- 예) 3단계의 step로 이루어진 코드 중, 3step를 테스트 할 때
- (기존) 1 -> 2 -> 3 step를 통해 테스트를 진행해야 함.
- 1, 2 step는 건너뛰고 바로 3step로 접근하는 backdoor 마련
- 더 낮은 비용으로, 더 자주 피드백 가능.
- 예) 3단계의 step로 이루어진 코드 중, 3step를 테스트 할 때
- 중복되는 비용을 최소화 시키는 나만의 방식을 개발해 나가야 함.
프로그래머만 TDD가 필요할까?
그렇지 않음. 어떤 목표를 정해두고, 해당 목표를 향해 나아가는데 있어 TDD의 업무 진행 방식은 빠르지는 않을 수 있으나, 높은 퀄리티의 결과물을 얻을 가능성이 높아짐.
본인의 목표를 이루기 위해, 내가 진행 중인 작업에 대해 나 또는 다른 사람에게 피드백을 자주 받는 것을 고려해야함.
- 예시. PPT 작성 시
- PPT의 핵심 메시지 및 파트 별 핵심 내용 선정 (테스트 코드 작성)
- PPT를 작성하며 수시로, 또는 파트 별로 자신의 메시지가 잘 드러나는지 검토 (유닛 테스트 진행)
- 충분한 의사 전달이 이루어지지 않았다면, 핵심 내용에 대한 언급 추가 (실패 및 코드 작성)
- 충분한 의사 전달이 이루어졌다면, 다음 파트 작성 (성공 및 확장, 리팩토링)
- 필요하지 않은 부분이거나, 잔가지는 과감히 쳐내는 것도 방법.
- 전체 PPT가 완성되면, 실제 발표 상황을 상상하며 읽어본다. (전체 기능 테스트)
- 발표를 듣는 사람 입장에서 생각해보면 좋음
참고 사이트
- https://wooaoe.tistory.com/33
- https://gmlwjd9405.github.io/2018/06/03/agile-tdd.html
- https://ahea.wordpress.com/2018/09/10/%EC%84%A0%ED%83%9D%EC%9D%B4-%EC%95%84%EB%8B%8C-%ED%95%84%EC%88%98-tdd/
댓글남기기