테스트의 가치는 단순히 모든 코드를 한 번 실행해봤다는 "커버리지 수치"에서 오는 것이 아니다.
오히려 중요한 건 다음과 같다.
100% 커버리지를 달성했다고 해도
→ 애플리케이션이 올바르게 동작하는 것을 보장하진 않는다.
| ❌ 좋지 않은 테스트 | ✅ 좋은 테스트 |
|---|---|
| 단순 실행만 해서 커버리지만 높이는 테스트 | 명확한 조건 → 기대 결과를 검증하는 테스트 |
| assert 없이 실행만 하고 끝남 | 실패/예외를 정확히 잡아내는 테스트 |
| 복잡한 로직을 무조건 cover만 하려는 테스트 | 예외 상황, 경계값을 고려한 케이스 중심 테스트 |
"테스트는 품질 보증 수단인 동시에, 코드 설계 도구다."
TDD(Test-Driven Development)는
테스트 기술이 아니라, 분석과 설계 기술이다.
📖 "TDD의 아이러니 중 하나는 테스트 기술이 아니라는 점이다.
TDD는 분석 기술이며, 설계 기술이기도 하다."
— 켄트 벡, Test-Driven Development by Example
| 단계 | 일반 개발 | TDD 개발 |
|---|---|---|
| 1단계 | 로직 먼저 작성 | 실패하는 테스트 먼저 작성 |
| 2단계 | 예외 처리 추가 | 예외 케이스 테스트부터 작성 |
| 3단계 | 테스트 작성 | 테스트 통과를 위한 최소 로직 작성 |
| 4단계 | 리팩터링 (종종 테스트 깨짐) | 테스트 통과를 유지한 채 구조를 정리 |
리팩터링이란 단순히 "코드를 다시 짠다"는 뜻이 아니다.
리팩터링은 동작은 그대로 두면서 코드의 구조만 개선하는 작업이어야 한다.
테스트가 깨진다면 → 그건 리팩터링이 아니라, 기능 변경이다.
리팩터링은 역할과 협력 구조를 재조정하는 작업이다.
결국 객체 간 메시지 흐름과 책임 분리를 명확히 이해해야 한다.
- 어떤 객체가 누구에게 메시지를 보내는가?
- 이 책임은 이 객체가 가져야 할 일인가?
- 테스트는 이 상호작용을 드러내고 있는가?
TDD를 잘 한다는 것은
단순히 테스트 코드를 먼저 쓰는 습관이 아니라,
기능 요구를 명확히 분석하고, 설계 방향을 명확히 표현할 수 있는 사고방식을 갖는 것이다.
테스트는 품질을 높이는 수단이기도 하지만,
그보다 더 근본적으로는 더 좋은 설계를 만들기 위한 도구다.
"좋은 테스트는 코드보다 먼저 명확한 생각을 요구한다."
https://dublin-java.tistory.com/57
https://engineerinsight.tistory.com/34
https://inpa.tistory.com/entry/QA-📚-TDD-방법론-테스트-주도-개발