TDD 사이클의 단계별 목표

2024. 9. 8. 18:33TDD

TDD 사이클은 빨강(테스트 작성) → 초록(테스트 통과) → 리팩토링(중복제거) 순으로, 반복적으로 진행한다. 해당 포스트에서는 TDD 사이클의 단계별 목표를 설명한다.
 

1. 먼저 테스트를 작성한다

이 단계는 '인터페이스'를 설계하는 단계이다. 기능의 사용법을 결정하고, 작동 여부를 확인하는 방식을 결정해야 한다. 기능을 사용하는(또는 예외가 발생하는) 구체적인 예제 코드를 생각하는 것이 좋다.
 
클래스 이름, 메서드 이름, 파라미터 개수 등을 정하고, 테스트 코드로 기능을 사용할 때 불편한 부분이 없는지 확인한다. 테스트 데이터는 대표적이면서 읽기 쉬운 것을 사용한다. 기능의 작동 여부를 확인하기 위해서 객체의 내부 상태를 사용하는 것은 좋지 않다. 테스트 코드에서 객체 내부에 대한 의존성이 생기면, 리팩토링 시 테스트 코드도 변경해야 한다.
 
왜곡된 기억일지 모르지만, 개인적으로 이 습관을 고치기가 제일 힘들었던 거 같다. TDD를 알기 전에는 '구현 코드'를 먼저 고민하는 습관이 있었다. 이후 습관을 고치기 위해 노력했다. IDE 에디터를 절반으로 갈라서 왼쪽에는 테스트 코드를, 오른쪽에는 구현 코드를 띄워서 작업하기도 했다. 의도적으로 '인터페이스' 설계와 '구현 코드' 설계를 분리해서 생각하고, '인터페이스' 설계를 먼저 고민하는 습관을 들였다.
 

2. 테스트를 실행하고 의도대로 실패하는지 확인한다

이 단계는 테스트를 실제로 실행하는 것이 중요하다. 테스트 실패(또는 성공)에 대한 추측이 사실인지 눈으로 확인하는 것이 중요하다. 실패할 것으로 예상하는 테스트가 통과하는 경우가 있다. 이 경우 원인을 찾아야 한다. 기존에 작성한 테스트와 중복되는 테스트일 수도 있고, 구현할 필요가 없는 기능일 수도 있다.
 

3. 빠르게 테스트를 통과시킨다

이 단계는 가능한 한 빨리 초록 막대를 보는 것이 중요하다. 제한 시간을 두는 것도 방법일 수 있다.
 
테스트를 통과하는 방법은 '가짜로 구현하기', '명백한 구현 사용하기', '테스트 삭제하기' 등이 있다. 이 단계에서는 구현 코드를 더럽게 작성해도 상관없다. 다음 단계에서 코드를 정리하기 때문이다. 통과하는 방법을 찾는 데 오랜 시간이 걸리는 테스트도 있다. 이런 테스트는 삭제 후 더 작은 테스트로 다시 작성하는 게 방법일 수 있다.
 
이 부분도 습관을 고치기 힘들었던 거 같다. '가짜로 구현하기'를 적극적으로 사용하면 좋다고 스스로를 세뇌했지만, 무의식적으로 "너무 멍청해 보이는 방법이다"라고 생각한 거 같다. 어쩌면 다른 우아한(?) 설계 방식에 대한 동경이 있었던 거 같기도 하다.
 

4. 느긋하게 코드 구조를 변경한다

이 단계는 '구현 코드'를 설계하는 단계이다. 여러 가지 설계 기법을 적용해서 실험하고, 검토를 통해 추가 작업이 없는지 확인한다.
 
리팩토링으로 중복코드를 제거하거나 코드 구조를 변경한다. 리팩토링 단위는 작업 리듬에 따라 조절한다. 잘 풀리면 큼직하게 시도하고, 그게 아니면 작은 단위로 시도한다. 코드를 변경할 때마다 전체 단위 테스트 실행해야 한다. 문제가 없다고 추측한 코드 변경이 실제로 문제가 없는지 확인해야 한다. 어느 정도 리팩토링이 끝나면 검토하는 시간을 갖는다. 적용한 설계를 눈으로 확인하고, 설계에 대한 다른 아이디어가 생각나면 테스트 목록에 추가한다.
 
TDD를 하면서 제일 좋아하는 단계이다. 이 단계를 하다 보면 설계를 발견한다는 느낌을 많이 받는다. TDD에 익숙해지기 전까지는, 최대한 작은 단위의 리팩토링을 한 번에 하나씩 적용하는 것이 좋다.
 

마치며

프로그래밍 문화에서 분할정복은 상식으로 통한다. 분할정복은 크고 복잡한 문제를 작고 단순한 문제로 쪼개서, 한 번에 하나씩 집중해서 해결할 수 있다는 점이 매력이다. TDD 사이클도 비슷하다. 인터페이스 설계와 구현 코드 설계를 분리해서 해결하고, 설계에 대한 작업자의 추측이 사실인지 한 번에 하나씩 확인하는 과정을 밟는다.
 
새로운 기술을 배울 때는 마음가짐과 주변 상황이 중요할 수 있다. "이거 괜찮아 보이네. 한 번 배워볼까?"라고 생각할 수 있고, "켄트 벡이 책을 팔아먹으려고 사기 쳤구나"라고 생각할 수도 있다. 또, 주변 사람들의 TDD에 대한 긍정적/부정적 평가에 영향을 받을 때도 많다. (필자는 몇 년 단위로 반복해서 'TDD 변절자'의 삶을 살았다)
 
TDD는 사고방식을 바꿔야 하므로 익숙해지기까지 시간이 필요하다. 당장 다음 주부터 잘할 수 없다. 조급한 마음보다 여유를 갖고 시도하는 편이 좋다. TDD 사이클의 단계별 목표를 의식해서 사용한다면, 익숙해지는 시간을 단축할 수 있다고 생각한다.