TDD란? (Test Driven Development)
테스트 주도 개발(TDD) 은 소프트웨어를 개발하는 여러 방법론 중 하나이다.
제품이 오류 없이 정상 작동하는지 확인하기 위해 모든 코드는 프로그래머가 작성하고 나서 테스트를 거치게 되는데,
TDD에서는 제품의 기능 구현을 위한 코드와 별개로, 해당 기능이 정상적으로 움직이는지 검증하기 위한 테스트 코드를 작성한다. 이를 통해 테스트가 실패할 경우, 테스트를 통과하기 위한 최소한으로 코드를 개선한다. 최종적으로 테스트에 성공한 코드를 리팩토링 하는 과정을 거친다.
TDD의 효과
- 코드가 내 손을 벗어나기 전에 가장 빠르게 피드백 받을 수 있다.
개발 프로세스에서는 보통 ‘인수 테스트’ 를 한다.
인수테스트란, 실제 사용자 환경에서 사용자(클라이언트)의 입장으로 소프트웨어 테스트를 수행하는 것을 말한다.
이미 90% 이상 완성된 코드를 가지고 테스트하기 때문에 문제를 발견할 수는 있다. 다만, 정확하게 원인이 무엇인지 진단하기는 힘들다.TDD를 사용하면 기능 단위로 테스트를 진행하기 때문에 코드가 모두 완성되어 프로그래머의 손을 떠나기 전에 피드백을 받는 것이 가능하다.
- 작성한 코드가 가지는 불안정성을 개선하여 생산성을 높일 수 있다.
TDD를 사용하면, 코드가 내 손을 떠나 사용자에게 도달하기 전에 문제가 없는지 먼저 진단 받을 수 있다.
이를 통해 코드가 지닌 불안정성과 불확실성을 지속적으로 해소해준다.
- 프로그래머의 오버 엔지니어링을 방지한다.
- TDD의 원칙 중 하나는, 테스트를 통과하기 위한 최소한의 코드만 작성 및 개선해야 한다는 것이다.
기능 단위로 테스트를 진행하기 때문에, 문제가 발견되지 않은 코드에 영향을 줄 수 있는 오버 코딩은 하지 않는다. - 개발 과정이 테스트 코드로 남기 때문에, 과거 의사결정을 쉽게 상기할 수 있다.
TDD를 사용하면, 테스트 코드를 작성하는 과정에서 히스토리가 남는다. 어떻게 보면 과거의 나 자신과 프로그래머가 협업하는 것을 용이하게 만들어준다고 할 수 있다. TDD를 통해 작성한 테스트 코드를 트래킹하면서 과거에 어떤 인과관계로 의사결정을 했는지 확인하기 쉽다.
TDD에 관한 편견과 실상
TDD는 무조건 해야 한다?
그렇지 않다. TDD가 프로그래머에게 주는 이점에 대해 나열하면, TDD가 모두에게 필요한 것처럼 느껴질 수 있다. 하지만 프로그래머가 코드를 작성해 기능 하나를 추가할 때마다, 시간이 늘어난다고 본다면 TDD는 오히려 비효율적인 것처럼 보이기도 한다. TDD를 사용했을 때의 초기 비용은 TDD를 사용하지 않았을 때보다 크기 때문이다.
하지만 TDD를 사용하기 시작하면 초기 비용은 더 많이 들 수 있으나 전체적으로 봤을 때 비용이 점진적으로 늘어나지 않는다는 것이다. 따라서, TDD를 위한 환경세팅이 이미 잘 되어 있는 업무 환경이라면 TDD를 사용하는 편이 장기적으로는 효과적이라 할 수 있다.
TDD는 버그를 박멸한다?
그렇지 않다. TDD는 버그를 없애주는 도구가 아니다.
오히려 TDD를 사용하면 더 많은 버그를 사전에 발견할 수 있다. 프로그래머가 작성한 코드가 사용자에게 도달하기 전에, 혹은 전체 코드를 완성하기 전에, 기능 단위로 문제를 개선할 수 있게끔 빠른 피드백을 전달하는 것이다. 그래서 버그를 보다 빠르고 효과적으로 개선할 수 있도록 프로그래머를 도와줄 수는 있다.
TDD는 항상 느리다?
그렇지 않다. TDD를 업무에 사용할 때 업무 속도가 느려진다고 느끼는 것에는 여러 이유가 있는데,
일단, TDD를 처음 도입하면 TDD를 사용하기 위해 필요한 초기 자원이 미진해서 속도가 나지 않는다고 생각할 수 있고,
테스트 코드 작성에 대한 업무 부담감도 한 몫 한다.테스트 자동화를 위해 필요한 코드까지 프로그래머가 작성하고 관리해야 하므로 업무가 오히려 더 늘어나 비효율적이라 여길 수 있다. 기억해야 할 것은 TDD 자체가 목적이 되어서는 안 된다는 사실이다. TDD는 공동의 목표를 효율적으로 달성하기 위한 도구이다.
테스트 기법의 종류와 장단점
- 수동 테스트
회사에서는 보통 QA라고 부르는 전문 담당자들이 UI를 활용해 기능을 검증한다. 사람이 검증하기 때문에, 사용자와 가장 가까운 관점에서 테스트가 가능하다. 소프트웨어의 모든 코드가 현장에 배치된 후에 테스트할 수 있다. 따라서 어떤 기능이 정상 작동하기 위해 필요한 모든 코드가 준비되어야 한다. 가장 온전한 전체 코드를 검증하는 테스트 방식이다.
- 테스트 자동화
수동 테스트가 지닌 한계를 보완하기 위해 등장한 도구이다. 사람이 직접 테스트하지 않고, 어떤 기능을 검증하는 또 다른 코드를 작성하는 방식이다.
단점은, 수동 테스트에 비해 프로그래머가 더 많은 코드를 작성해야 한다는 점이다. 운영 코드를 테스트하기 위한 별도의 코드를 추가 작성해야 하기 때문이다. 테스트 코드의 작성과 관리가 프로그래머 개인의 역량에 달려 있어, 업무 자체가 허들이 될 수도 있다.
반면, 테스트에 드는 비용은 매우 낮아진다는 점이 장점이다. 수동 테스트에 비해 테스트 자체에 대한 신뢰도도 매우 높아진다.
- 인수 테스트
배치된 시스템을 대상으로 검증하는 방식으로, 주로 클라이언트가 의뢰한 소프트웨어를 최종적으로 사용할 수 있는 수준인지 점검하는 테스트이다. 전체 시스템의 이상 여부가 없는지 확인하며, 사용자 관점으로 체크하기 때문에 신뢰도가 높은 테스트 방법이다.
단, 비용이 매우 높다. 코드 작성부터 관리, 테스트 실행까지 자원이 많이 들어간다. 또한 프로그래머 입장에서 받을 수 있는 피드백의 질이 떨어진다. 문제는 파악할 수 있으나, 그 원인까지 단번에 알려주지는 못하기 때문이다.
- 단위 테스트 (Unit Test)
단위 테스트는 시스템의 일부(하위 시스템)를 대상으로 기능을 검증하는 테스트이다. 전체 시스템을 배치해놓고 진행하지 않으므로, 비용이 상대적으로 낮은 편이다.
인수 테스트와 비교해서, 단위 안에서 버그가 있다는 걸 상대적으로 자세히 알 수 있다. 따라서 프로그래머 입장에서는 문제 해결을 위해 필요한 피드백을 적절하게 받을 수 있다. 하지만 전체 시스템의 이상 여부를 판단하는 신뢰도는 낮아진다. 단위 테스트에서 문제가 없다고 판단되어도, 전체 시스템이 유기적으로 연결될 때 오류가 날 수도 있기 때문이다.
테스트 주도 개발 프로세스
TDD 메인 프로세스
- RED : 테스트 실패
- 실패하는 테스트 추가
- 구체적인 하나의 요구사항을 검증하는 하나의 테스트를 추가한다. 추가된 테스트가 실패하는지 확인한다.
- GREEN : 테스트 통과
- 최소한의 코딩, 그 이상을 변경하거나 추가하면 안 된다.
- 코드가 중간에 추가되면, 이후 리팩토링 등의 다른 프로세스에서 어떤 부작용을 가져올지 알 수 없기 때문이다.
- 추가된 테스트를 포함하여, 모든 테스트가 성공하게끔 운영 코드를 변경한다.
- REFACTOR : 구현 설계 개선
- 테스트 통과 유지
- 코드베이스를 정리, 구현 설계 개선
단위테스트시 참고사항
- 단위 테스트는 버그를 찾기 위한 것이 아니다.
- 하나의 테스트 케이스는 단위 기능 중 하나의 시나리오만 테스트하라.
- 불필요한 검증 구문을 작성하지 마라.
- 각 테스트는 독립적이어야 한다.
- 단위 테스트 케이스의 이름은 명확하고 일관되게 테스트의 의미를 반영해야한다.
출처
'FRONTEND > Javascript' 카테고리의 다른 글
220801 Typescript Destructuring (0) | 2022.08.01 |
---|---|
220801 Typescript Handbook (0) | 2022.08.01 |
211105 Javascript - Array 에서 최소, 최대 값(Min/Max) 구하기 (0) | 2022.01.13 |
211201 Javascript Module Export & Import (0) | 2021.12.02 |
210708_Virtual DOM 이 빠른 이유 (0) | 2021.07.08 |
댓글