Test-Driven Development (테스트 주도형 개발)
매우 짧은 사이클의 반복에 의존하는 소프트웨어 개발 프로세스
테스트가 전체 개발을 주도한다
개발자는 요구사항의 자동화 테스트케이스 만들고,
해당 테스트케이스를 통과하는 코드를 만들어 리팩토링을 거치며 개선시키는 과정
일반 SW 개발
로직에 해당되는 코드의 작성을 끝내고, 그 코드의 검증을 위한 테스트케이스를 작성
TDD
요구사항에 따라서, 프로그램이 동작해야하는 기능에 대한 테스트를 먼저 만듦
⇒ 그리고 이런 테스트케이스를 통과하기 위한 로직의 코드를 짜는 것으로 순서를 역전
e.g., 2개의 정수를 입력 받으면 두 정수의 합을 출력하는 프로그램
간단한 목표 설정
→ 차례로 3과 5를 입력 받으면 8이 출력되야한다.
테스트케이스 설계
→ 3과 5을 입력 받으면, (아직 만들지 않은 코드를 통해서)8이 출력되는 테스트 프로그램
해당 테스트케이스를 통과할 코드 작성
→ 두 input 정수를 확인 후 덧셈을 return하는 코드
// python3
// 입력은 두 정수가 한 칸의 공백과 함께 한 줄로 동시에 주어진다고 가정
// Ex) >> a b
x, y = map(int, input().split())
return x + y
위에서 작성한 코드를 통해서 테스트 프로그램 수행
→ 3과 5를 입력 받으면, 위의 코드를 통해 8이 출력되야함
5-1. 통과 시, 새로운 테스트를 추가하며, 해당 테스트에 맞게 코드를 리팩토링 및 폴리싱
5-2. 실패 시, 통과할 때까지 코드를 수정
개발자는 구현하려는 기능의 요구사항에 온전히 집중할 수 있음
TDD의 순서에 맞춰서 테스트를 먼저 작성하게 됨
→ 개발자는 테스트 작성을 위해 기능의 요구사항과 명세를 사전에 완벽하게 이해해야함
⇒ 유저 케이스, 스토리 등을 참고하여 요구사항을 분석하는 과정을 통해 구현 목표가 뚜렷해짐
새로운 기능 추가할 때 마다, 새로운 기능과 기존 기능이 동시에 잘 작동하는 지 확인 가능
새로운 기능을 추가하면 기존 기능이 제대로 동작하지 않을 수도 있음
→ 이를 방지하고자 각 기능에 대한 테스트케이스를 만들고, 기능이 추가될 때마다 해당 테스트케이스를 추가
⇒ 기능이 추가될 때 마다 전체 테스트를 수행하며 각 기능을 점검할 수 있음
리팩토링에 도움이 됨
코드가 커지면, 가독성과 coding convention, 확장성과 비즈니스 로직등의 개선을 위해 리팩토링을 수행
→ TDD로 개발 시, 테스트 코드가 리팩토링이 잘 되고 있는지의 척도로 사용될 수 있음
(리팩토링 작업에서 간헐적으로 테스트를 수행하며 기능이 이상 없는지 점검)
⇒ 리팩토링 작업 속도가 빨라짐
→ 그만큼 퀄리티가 개선됨 (퀄리티: 객체지향적인가, 확장이 용이한가, 디버깅 시간 감소 등)
기능 점검과 테스트 문서 작성에 도움이 됨
테스트는 코드 작성 후 기능의 점검을 위해 필요하고, 테스트 내용을 기록하는 문서의 작성도 요구됨
→ TDD는 이 두 가지를 자연스럽게 충족시켜줄 수 있음
⇒ 뿐만 아니라 더 나아가 코드의 개발에도 도움(요구사항 집중, 신 기능 점검, 리팩토링)을 줌
전체적인 개발 시간이 늘어남
매 기능마다 테스트케이스를 만들고, 로직을 만들어야되므로 일이 늘어나기 때문
특히, 단기적인 성과에 집중하는 기업의 입장에서는 민감할 수도 있음
배보다 배꼽이 커질 수도 있음
어떤 기능에 대해, 다양한 테스트 케이스와 예외 테스트 케이스가 많아져 부담이 생길 수 있음
더군다나, 테스트 코드와 로직 코드의 주객이 전도되는 상황이 될 우려도 있음
→ 테스트를 위해 로직 코드의 구조를 바꿔야하는 경우가 발생할 수도 있음
어려움
일반적으로 코딩하던 습관 및 방식의 전환이 필요하기 때문
특히, 일반적인 방법으로 이미 내공이 쌓인 경력자일수록 바꾸기 힘듦 (Unlearning이 요구됨)
(반대로 개발 경력이 적은 사람이 TDD 적응이 쉽다고 함)
진입 장벽이 있음
기능에서 어떤 부분을 어떻게 테스트해야하는지 설정하는 방법부터,
개발 중인 서비스에 맞는 테스트 프레임워크의 선정까지 어느 정도의 사전학습이 요구됨
특히 개발은 팀 단위로 진행되므로, TDD 적용을 위해서 팀원이 전체적으로 TDD에 대한 이해도가 있어야 함
편견과 일반화가 생김
정해진 툴(단위 테스트 프레임워크)을 이용해야한다는 강박이 생기거나 융통성이 없어질 수도 있음
정해진 규칙이나 방식에 얽매어 agile하지 않게 되므로 TDD 구현이 어려워질 수도 있음