테스트는 계속 통과하지만, 디자인은 움직이지 않을 때
Source: Dev.to
디자인 정체 문제
TDD를 실천하다 보면 반복되는 순간이 있습니다: 테스트는 통과하고, 커버리지는 늘어나며, 리팩터링은 안전하게 느껴집니다. 그런데 어느 순간 디자인이 움직이기 시작하지 않죠. 시스템이 완성됐거나 문제가 해결돼서가 아니라, 테스트가 더 이상 새로운 것을 도전하지 않기 때문입니다. 이미 확정된 결정들을 계속 확인하고 있을 뿐입니다.
정체는 미묘합니다—명백히 잘못된 것은 없지만 학습 속도가 거의 멈춥니다. 새로운 테스트마다 필연적으로 보이고, 시스템은 여전히 변하지만 오래전 정해진 경계 안에서만 변합니다.
테스트가 역할을 바꾸는 방식
테스트를 잘못 작성해서 이런 일이 일어나는 것이 아니라, 테스트가 조용히 역할을 바꾸면서 발생합니다. 처음엔 테스트가 탐색적이지만, 시간이 지나면서 많은 테스트가 다른 것이 됩니다. 그때부터는 초록색 테스트가 의심을 줄여주지 않으며, 피드백 루프는 여전히 돌아가고 있습니다.
돌아보면, 디자인이 정체된 것이 놀라운 것이 아니라, 몇몇 가정이 너무 일찍 굳어버렸다는 점이 놀라웠습니다—대개 명시적으로 설계되지 않은 채:
- 클래스 경계
- 데이터 형태
- 통합 지점
- 테스트가 주장한 것과 주장하지 않은 것
이러한 가정이 충분히 깊게 코드에 녹아들면, 디자인 작업이 실제로 멈춘 것은 아니지만 더 이상 필요하다고 느껴지지 않습니다.
디자인을 다시 불붙이는 실험
이 깨달음은 몇 가지 불편한 실험으로 나를 이끌었습니다:
- 합리적이라고 생각되는 시점보다 훨씬 앞서 엔드‑투‑엔드 테스트를 작성하기.
- 기능보다는 시스템이 어떻게 진화하든 절대 깨지면 안 되는 것이 무엇인지에 초점을 맞추기.
- 실제로 나에게 무엇이 변했는지에 주의를 기울이기.
대부분 경우, 변화는 정확성에 대한 자신감이 아니라 디자인을 다시 질문할 필요성을 느끼지 못하게 된 순간이었습니다. 이것이 더 많은 테스트를 요구한다는 주장은 아닙니다. 중요한 것은 테스트가 어디에 위치했는지가 아니라, 어떤 종류의 압력을 가했는가입니다. 일부 테스트는 단지 부품들이 맞물리는지를 검증합니다; 그런 충돌은 불편하지만 디자인이 다시 움직이기 시작하는 지점이기도 합니다.
이것이 아닌 것
테스트가 디자인 작업을 대체해야 한다는 주장이 아닙니다. 단지 몇몇 가정이 문서상으로는 안정적으로 보이지만, 그런 경우 특정 테스트가 디자인을 대신하지 못한다는 관찰입니다.
AI‑보조 코딩 시대의 함의
최근 이 질문이 더욱 시급하게 느껴집니다. AI‑보조 코딩을 사용하면 설득력 있는 구현을 쉽게 만들고, 테스트를 통과시키며, 리팩터링을 설득할 수 있습니다. 초록색이 저렴해지면서 가정이 눈에 띄지 않게 정착되기 쉬워집니다. 테스트가 구조만 확인한다면, 진짜 질문은 다음과 같습니다:
디자인이 멈추는 것을 누가 여전히 감시해야 할까?
테스트와 디자인 관계 재구성
새로운 방법론을 제안하는 것이 아니라 관점을 바꾸고자 합니다. 디자인은 테스트에 앞서는 단계가 아닙니다. 가장 유용한 형태의 테스트는 의심을 일으키는 도구입니다. 테스트가 그 목적을 잃으면, 무언가 잘못됐다는 신호이며, 앞으로 나아갈 길을 찾는 것이 작업입니다.
초록색 테스트가 “이 부분이 올바르다”는 의미는 아닙니다. 때때로 그것은 가정이 조용히 질문받지 않게 되었음을 의미합니다. 디자인이 멈출 때, 그것이 내가 아직 이해하려는 부분입니다.