본문 바로가기

독서찰기(讀書札記)/단위 테스트

좋은 단위 테스트의 4대 요소

  • 회귀 방지
  • 리팩터링 내성
  • 빠른 피드백
  • 유지 보수성

1.  회귀 방지

회귀 = 소프트웨어 버그 : 코드를 수정한 후 기능이 의도한 대로 작동하지 않는 것

코드베이스가 커질수록 잠재적인 버그에 더 많이 노출되기 때문에 회귀에 대해 효과적인 보호를 개발하는 것이 중요하다.

회귀 방지를 위한 고려사항

  • 테스트 중에 실행되는 코드의 양
  • 코드 복잡도
  • 코드의 도메인 유사성

실행되는 코드가 적을수록 회귀가 나타날 가능성이 낮다.

복잡한 비즈니스 로직을 나타내는 코드가 boilerplate code보다 훨씬 더 중요하다. 비즈니스에서 중요한 기능에서 발생한 버그가 가장 큰 피해를 입히기 때문이다.

우리가 작성하지 않은 코드(라이브러리, 프레임워크, 외부 시스템 등등)도 중요하다.

2.  리팩터링 내성

거짓 양성(false positive) : 실제로 기능이 의도한대로 작동하지만 테스트는 실패를 나타내는 것

리팩터링 후에도 기능이 완벽하게 작동하는데, 기반 코드의 변경으로 인해 테스트가 실패한다면 리팩터링 내성이 없는 테스트 코드이다.

리팩터링 내성을 위해서는 거짓 양성이 적을수록 좋다.

거짓 양성의 위험성

  • 테스트가 타당한 이유 없이 실패하면, 점점 그러한 실패에 익숙해지고 그만큼 신경을 많이 쓰지 않는다. 나중에는 타당한 실패도 무시하기 시작한다.
  • 테스트 스위트에 대한 신뢰도가 떨어져 더 이상 안전망의 역할을 하지 못한다. 신뢰가 부족해지면 리팩터링이 줄어든다.

거짓 양성의 원인

테스트와 테스트 대상 시스템(SUT)의 구현 세부 사항이 많이 결합할수록 허위 경보가 더 많이 생긴다.

구현 세부 사항에서 테스트를 분리하고, SUT가 제공하는 최종 결과를 검증하는지 확인해야 한다.

테스트를 구성하기에 가장 좋은 방법은 문제 영역에 대해 이야기하는 것이다.

3.  빠른 피드백, 유지 보수성

테스트 속도가 빠를수록 스위트에서 더 많은 테스트를 수행할 수 있고 더 자주 실행할 수 있다.

테스트가 빠르게 실행되면 피드백 루프를 대폭 줄여서, 버그를 수정하는 비용을 거의 0까지 줄일 수 있다.

유지 보수성 지표를 위한 고려사항

  • 테스트가 얼마나 이해하기 어려운가
    • 코드 라인이 적을수록 더 읽기 쉽다.
    • 테스트 코드의 품질은 제품 코드만큼 중요하다.
  • 테스트가 얼마나 실행하기 어려운가
    • 테스트가 프로세스 외부 종속성으로 작동하면, 의존성을 상시 운영하는 데 시간을 들여야 한다.