1. 단위 테스트 현황
- 기업용 애플리케이션 개발 프로젝트는 대부분 단위 테스트를 적용하고 있습니다.
- 다수의 단위 테스트와 통합 테스트를 통해 양호한 코드 커버리지를 확보하고 있습니다.
- 제품 코드 대비 테스트 코드의 비율이 꾸준히 높아지고 있습니다.
- 단위 테스트 논쟁은
단위 테스트를 작성해야 하는가?에서좋은 단위 테스트란 무엇인가?로 무게중심이 이동했습니다.
2. 단위 테스트의 목표
- 단위 테스트 활동은 더 나은 설계를 촉진하지만, 이는 부수 효과일 뿐 핵심 목표는 아닙니다.
- 단위 테스트의 궁극적인 목표는 소프트웨어 프로젝트의 지속 가능한 성장을 가능하게 하는 것입니다.
2.1 테스트가 없는 일반 프로젝트
- 초반에는 제약이 없어 빠르게 개발을 시작할 수 있습니다.
- 잘못된 아키텍처 결정이 누적되지 않아 우려할 만한 코드가 거의 없습니다.
- 시간이 지날수록 수정 비용이 급증해 개발 속도가 크게 떨어지며, 경우에 따라 거의 멈출 수 있습니다.
- 이러한 급격한 속도 저하는 소프트웨어 엔트로피로 불립니다.
- 코드베이스를 변경할 때마다 무질서도(엔트로피)가 증가합니다.
- 지속적인 정리와 리팩터링이 없다면 시스템은 점점 더 복잡하고 무질서해집니다.
2.2 테스트가 있는 프로젝트
- 테스트는 안전망 역할을 수행하며 대부분의 회귀에 대한 보험을 제공합니다.
- 새로운 기능을 도입하거나 요구 사항에 맞게 리팩터링한 뒤에도 기존 기능이 잘 작동하는지 확인하는 데 큰 도움이 됩니다.
- 단점은 초기 투자 비용이 크다는 점입니다.
- 그러나 프로젝트 후반에도 성장성을 유지할 수 있으므로 장기적으로는 투자 대비 효과가 큽니다.
- 코드베이스를 지속적으로 검증하는 테스트 없이는 개발을 안정적으로 확장하기 어렵습니다.
- 지속성과 확장성이 장기적인 개발 속도를 좌우합니다.
회귀
회귀는 코드 수정과 같은 사건 이후 기능이 의도한 대로 작동하지 않는 경우를 의미합니다. 소프트웨어 버그와 회귀는 사실상 동의어로 사용됩니다.
2.3 좋은 테스트와 좋지 않은 테스트를 가르는 요인
- 단위 테스트가 프로젝트 성장에 도움이 되는 것은 사실이지만, 단순히 테스트를 작성하는 것만으로는 충분하지 않습니다.
- 좋지 않은 테스트는 초반 품질 저하를 다소 늦출 수 있으나 장기적으로는 큰 차이를 만들지 못합니다.
- 좋지 않은 테스트는 잘못된 경고를 발생시키고 버그를 찾아내지 못하며 유지 보수가 어렵고 느립니다.
- 그러한 테스트를 많이 실행하더라도 단위 테스트의 목표를 달성할 수 없습니다.
- 지속 가능한 프로젝트 성장을 위해서는 고품질 테스트에만 집중해야 합니다. 이러한 테스트만이 테스트 스위트에 남을 가치가 있습니다.
3. 코드 커버리지
- 테스트 스위트의 품질을 간접적으로 파악하기 위해 코드 커버리지 지표를 참고하기도 합니다.
- 일반적으로 커버리지 수치가 높을수록 더 나은 것으로 간주됩니다.
- 그러나 코드 커버리지는 중요한 피드백을 제공하더라도 테스트 스위트 품질을 직접적으로 측정하지는 못합니다.
- 성공적인 테스트 스위트를 보장하지 않으므로 개발자는 스스로 좋은 테스트를 구별할 수 있어야 합니다.
- 코드 커버리지와 테스트 스위트 품질의 관계는
Code-Coverage.md문서에서 자세히 확인할 수 있습니다.
4. 좋은 테스트 스위트의 특성
4.1 개발 주기에 통합돼 있다
- 모든 테스트는 개발 주기에 긴밀하게 통합돼 있어야 합니다.
- 테스트를 빌드 시스템에 연동해 자동으로 실행되도록 구성합니다.
- 이상적으로는 코드가 조금이라도 변경될 때마다 테스트를 실행해야 합니다.
4.2 코드베이스 중 가장 중요한 부분만을 대상으로 한다
- 단위 테스트 관점에서 코드베이스 모든 부분을 동일하게 다룰 필요는 없습니다.
- 시스템의 가장 중요한 부분 에 단위 테스트 노력을 집중하고, 나머지는 간단히 또는 간접적으로 검증하는 편이 효율적입니다.
- 애플리케이션에서 가장 중요한 부분은 비즈니스 로직이 위치한 영역입니다.
- 비즈니스 로직 테스트가 시간 대비 최고의 투자 대비 효과를 제공합니다.
- 다른 부분은 세 가지 범주로 구분할 수 있습니다.
- 인프라 코드입니다.
- 데이터베이스 같은 외부 서비스 및 종속성입니다.
- 모든 요소를 하나로 묶는 글루 코드입니다.
- 통합 테스트를 통해 도메인 모델 밖의 영역까지 포함해 시스템 전체 동작을 확인할 수 있습니다.
- 이는 유용한 방법이지만 초점은 항상 도메인 모델에 머물러야 합니다.
4.3 최소한의 유지비로 최대의 가치를 끌어낸다
- 테스트를 시스템에 통합하고 높은 커버리지를 유지하는 것만으로는 충분하지 않습니다.
- 가치 있는 테스트를 식별하고 작성하는 일이 가장 중요합니다.
- 가치가 유지비를 상회하는 테스트만 테스트 스위트에 남겨야 합니다.
5. 결론
- 단위 테스트의 목적은 프로젝트가 장기적으로 지속 가능한 속 도를 유지하도록 돕는 데 있습니다.
- 고품질 테스트는 회귀를 조기에 차단하고 비즈니스 로직에 대한 자신감을 높여 개발 속도를 지킵니다.
- 커버리지 수치에 집착하기보다 가치 있는 테스트를 선별해 유지보수 비용을 통제하는 것이 바람직합니다.