TDD(Test Driven Development)
November 04, 2022
TDD
TDD란 Test Driven Development의 약자로 테스트 주도 개발을 의미한다. 요구상항은 계속 변하는데, 서비스의 품질을 항상 안정적으로 유지해야 하기 때문에 TDD를 해야 한다.
-
요구사항 변경
- 새로운 기능 추가
- 기존 기능 변경
- 기능은 그대로지만 기술적 변경
- 기능은 그대로지만 디자인 변경
- 이외에도 개발팀에서 대응해야 하는 모든 변경사항
- -
-
TDD 사이클
- 빨강 - 실패하는 작은 테스트를 빨리 작성한다. 처음에는 컴파일조차 되지 않을 수 있다.
- 초록 - 빨강 테스트가 통과하게끔 간단하게 만든다. 이를 위해 어떤 죄악을 저질러도 좋다.
- 리팩토링 - 일단 테스트를 통과하게만 하는 와중에 생겨난 모든 중복을 제거한다.
TDD의 궁극적인 목적은 작동하는
깔끔한 코드
를 얻는 것이다.
한번에 이루기는 어려운 목표이므로 나누어서 정복하자(divide and conquer).
일단 ‘작동하는’에 해당하는 문제를 먼저 해결하고, ‘깔끔한 코드’ 부분을 해결한다.
일단 동작하는 쓰레기라도 만들고, 이후 계속해서 리팩터링하여 깔끔한 코드로 거듭날 수 있게 하는 기반을 만드는 것이 TDD다.
리팩터링이란
리팩터링이란 기능을 구대로 유지한 채, 내부 구현만 개선하는 것이다. 그런데 리팩터링을 했을 때, 기능이 잘 동작한다는 것을 어떻게 보장할까? TDD를 통해 가능하다. TDD는 프로그래밍을 하면서 나타나는 두려움을 관리하는 방법이다.
테스트 종류
-
E2E 테스트
- slower, expensive
-
Unit 테스트
- faster, cheaper
웹 프론트엔드에서 주로 하는 일은 다음과 같다.
-
네트워크
- 애플리케이션 서버 외부 API
-
상태
- 도메인 데지터 비즈니스 로직
-
UI
- 브라우저 렌더링, 사용자 인터랙션
E2E 테스트는 네트워크
, 상태
, UI
까지 왔다갔다하며 전체를 다 테스트한다.
UNIT 테스트는 상태
등 더 작은 단위인 개별 영역에 대해서만 테스트한다.
즉, E2E 테스트와 UNIT 테스트의 차이는 테스트 대상과 범위가 달라지는 데 있다.
E2E 테스트는 실제 앱의 동작을 그대로 테스트할 수 있지만, 그렇기 때문에 다음과 같은 단점이 있다.
- 피드백 주기가 긴 편이다. 하나의 케이스를 통과하기 위해 많은 것을 구현해야 한다.
- 테스트가 실패하는 이유가 여러가지일 수 있다.
- 테스트 작성 비용도 크다.
- 랜덤 등 제어할 수 없는 대상에 대해서는 테스트가 어렵다.
Given / When / Then 패턴
-
Given (주어진 환경) : 특정 값이 주어지고(Given)
- 유저에게 계산기 화면이 렌더링 된 후
-
When (행위) : 어떤 이벤트가 발생했을 때(When)
- 유저가 숫자 4을 클릭한다.
- 유저가 + 버튼을 클릭한다
- 유저가 2를 클릭한다.
- 유저가 = 을 클릭한다.
-
Then (기대결과) : 그에 대한 결과를 보장해야 한다(Then).
- 계산기 화면에는 6이라는 숫자가 보여진다.
TDD에 대한 생각
우테코에서 들은 TDD에 대한 여러 생각들이다. 고민해보자.
- 무엇을 테스트하지 않을지를 결정해야 한다. 불필요한 곳에서는 테스트하지 않고 핵심적인 곳에만 테스트를 유지해도 좋다.
- 테스트하기 어려운 코드들이 섞여 있으면 단위테스트하기 어렵다. 따라서 테스트하기 어려운 코드를 분리하여 개발하는 역량을 키워야 한다. 테스트하기 어려운 코드는 테스트하지 않는다.
- 현업에서는 서비스 성격에 따라, E2E테스트와 유닛테스트를 동시에 사용하는 등 중요도가 달라진다. E2E는 작성 비용도 크고 실행 속도도 상대적으로 느리다보니, 가장 서비스에서 중요한 사용 플로우(ex, 결제시스템)에 제한적으로 사용하는 편이다.
- 시간이 지나서 레거시가 쌓일수록 테스트의 중요성이 커진다.
- 처음부터 설계를 완벽히 할 수 없다. 설계는 끊임없이 계속 해야 한다. 작은 단위의 설계 변경을 게속해야 한다. 그럴려면 테스트코드가 바탕이 되어야 한다. TDD는 리듬을 타면 재밌다.
- 테스트하기 쉬운 코드를 만들다보면, 조금 더 유연한 코드(유지보수하기 좋은 코드)를 만들 가능성이 높아진다.
- 테스트 코드도 ‘코드’다. 유지보수의 대상이며, 작성하는 비용 대비 효용을 생각할 필요도 있다.