테스트 주도 개발(TDD)
테스트 주도 개발이란
TDD란 Test Driven Development의 약자로 ‘테스트 주도 개발’이라고 한다.
테스트 코드를 먼저 작성한 후, 구현 코드 작성 단계와 리팩토링 단계를 짧은 주기로 반복하여 개발하는것이다.
보통의 경우 코드를 만든후 테스트를 한다. 이순서를 바꾸어 테스트를하고 코드를 만드는것이 TDD이다.
테스트 코드를 작성하여 프로그램이 잘못되었음을 증명하고, 잘못된 부분을 수정하여 목표에 부합할 만큼 참으로 만드는 개발 방법론이다.
TDD 개발주기
Red
작성하고자 하는 메소드나 기능이 무엇인지 선별하고 작성 완료 조건을 정해서 실패하는 테스트 케이스를 작성하는 행위이다.
TDD에서 가장 중요한 부분이자 가장 어려운 부분이다.
모든 케이스를 예상하여 내가 짠 코드가 올바르지 않음을 증명해야 한다.
Green
테스트 케이스를 통과하는 코드를 작성하는 과정이다.
리턴타입은 null, 0 등으로 설정하고 시작한다.
todo list를 작성하며 진행한다. 실패한 테스트에 대해 All Green이 나오도록 작성해야 한다.
Refactor
todo목록을 지우면서 리팩토링이 필요한지 확인한다.
소스의 가독성이 적절한지, 중복된 코드가 없는지, 이름이 잘못 부여된 메서드나 변수명은 없는지, 구조의 개선이 필요한지 확인한다.
TDD방식과 일반 방식 비교
일반 개발 방식
보통 개발 방식은 ‘요구사항 분석 → 설계 → 개발 → 테스트 → 배포’의 형태의 개발 주기를 갖는다.
이러한 방식은 개발을 느리게할 수 도있다.
- 소비자의 요구사항이 처음부터 명확하지 않을 수 있다.
- 처음부터 완벽한 설계는 어렵다.
- 자체 버그 검출 능력 저하 또는 소스코드의 품질이 저하될 수 있다.
- 테스트 비용이 증가할 수 있다.
고객의 요구사항 또는 설계 오류 등 많은 외부 또는 내부 조건에 의해 재설계하여 점진적으로 완벽한 설계로 나아간다.
재설계로 인해 개발자는 코드를 삽입, 수정, 삭제하는 과정에서 불필요한 코드가 남거나 중복될 가능성이 있다.
이러한 코드들은 재사용이 어렵고 관리가 어려워서 유지보수를 어렵게 만든다.
작은 부분의 기능 수정에도 모든 부분을 테스트해야 하므로 전체적인 버그를 검출하기 어려워진다. 그 결과 어디서 버그가 발생할지 모르기 때문에 잘못된 코드도 고치지 않으려 하는 현상이 나타나게 된다.
이현상은 소스코드의 품질 저화와 직결되고, 작은 수정에도 모든 기능을 다시 테스트해야하는 문제가 발생하여 테스트 비용이 증가한다.
TDD 개발 방식
TDD는 테스트 코드를 작성한 뒤에 실제 코드를 작성한다.
설계 단계에서 프로그래밍 목적을 반드시 미리 정의해야하고, 테스트 케이스를 미리 정의해야 한다.
테스트 코드를 작성하는 도중 발생하는 예외 사항은 테스트 케이스에 추가하고 설계를 개선한다.
그후 테스트가 통과된 코드만을 코드 개발 단계에서 실제 코드로 작성한다.
TDD 개발 방식의 장점
객체 지향적인 코드 생산
TDD는 코드의 재사용 보장을 명시하므로 TDD를 통한 소프트웨어 개발 시 기능 별 철저한 모듈화가 이뤄진다.
이는 종속성과 이존성이 낮은 모듈로 조합된 소프트웨어 개발을 가능하게 하며 필요에 따라 모듈을 추가하거나 제거해도 소프트웨어 전체 구조에 영향을 미치지 않게 된다.
재설계 시간 단축
테스트 코드를 먼저 작성하기 때문에 개발자가 지금 무엇을 해야하는지 분명히 정의하고 개발을 시작하게된다. 또한 테스트 시나리오를 작성ㄹ하면서 다양한 예외사항에 대해 생각해 볼 수 있다. 이는 개발 진행 중 소프트웨어의 전반적인 설계가 변경되는 일을 방지할 수 있다.
디버깅 시간 단축
유닛 테스트의 이점이기도하다. 예를 들어 사용자 데이터가 잘못되었다면 DB의 문제인지, 비즈니스 로직의 문제인지, UI의 문제인지 모든 부분들을 디버딩 해야하지만, TDD의 경우 자동화 된 유닛 테스트를 전제하므로 특정 버그를 손 쉽게 찾아낼 수 있다.
추가 구현 용이
개발이 완려된 소프트웨어에 어떤 기능을 추가할 때 가장 우려되는 점은 해당 기능이 기존 코드에 어떤 영향을 미칠지 알지 못한다는 것이다. 하지만 TDD의 경우 자동화된 유닛 테스트를 전제하므로 테스트 기간을 획기적으로 단축시킬 수 있다.
TDD 개발 방식의 단점
생산성 저하
개발 속도가 느려지게된다. 왜냐하면 처음부터 2개의 코드를 짜야하고 중간중간 테스트를 하면서 고쳐나가야하기 때문이다.
TDD 방식의 개발 시간은 일반적인 방식에 비해 10~30% 정도로 늘어난다.
TDD의 의미
- TDD는 정형적인 방법으로 하는 것이 중요한 것이 아니라 내가 스스로 TDD라고 하는 방식을 계속해서 발전시켜 나가는 것이 중요하다.
- 내가 이것을 왜하는가를 생각해야 한다.
- 피드백과 협력을 증진시키지 않으며 TDD를 하면 아무 의미가 없다.
- 혼자서만 TDD하면 피드백은 되겠지만, 협력이 증진이 되지 않는다.
- 즉, 정답이 있는것이 아니라 본인이 어떻게 발전시키느냐가 애자일의 핵심이다.
마치며
TDD는 결정과 피드백 사이의 갭에 대한 인식, 더 나아가 결정과 피드백 사이의 갭을 조절하기 위한 테크닉이다.
- 결정
개발할때 ‘이 방법으로 짤것이다.’, ‘이 부분은 이걸 사용할것이다.’라는 것을 결정한다.
- 피드백
성공 실패라는 피드백
TDD를 하면 피드백이 증가한다.
테스트를 통과하는 것으로 잘되고 있는지 자주 확인할 수 있다.
TDD를 하면 협력이 증가한다.
테스트 코드를 남들에게 보여줄 수 있고, 그 코드를 실행 해볼 수 있다. 즉 공유하기가 쉬워진다. 공유하면 협력이 증진된다. 남이 짠 코드를 빨리, 쉽게 이해할 수 있기 때문이다.
불확실성이 높을 때 ‘피드백’과 ‘협력’이 중요하다. TDD는 ‘피드백’과 ‘협력’을 증진시키는 것이기 때문에 불확실성이 높을 때 도움이 된다.
참고
https://hanamon.kr/tdd란-테스트-주도-개발/
https://gmlwjd9405.github.io/2018/06/03/agile-tdd.html
https://velog.io/@modolee/tdd-overview
https://www.guru99.com/test-driven-development.html
https://www.browserstack.com/guide/what-is-test-driven-development