요약

좋은 단위테스트의 네 가지 특성은 다음과 같다.

  1. 회귀 방지
  2. 리팩터링 내성
  3. 빠른 피드백
  4. 유지 보수성

이상적인 테스트는 4가지를 모두 만족하는 것이지만 회귀 방지, 리팩터링 내성, 빠른 피드백은 상호 배타적이므로 달성할 수 없다.

하지만 특정 특성에 집중하고 다른 특성을 버릴 수 없다. 이러한 테스트는 가치가 없다.

1. 회귀 방지

코드를 수정한 후 기능이 의도한 대로 작동하지 않는 경우를 의미한다.

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

회귀 방지 지표에 대한 평가 사항

  • 테스트 중 실행되는 코드의 양
    • 일반적으로 실행되는 코드가 많을수록 테스트에서 회귀가 나타날 가능성이 높다.
  • 코드 복잡도코드의 도메인 유의성
    • 복잡한 비즈니스 로직을 나타내는 코드가 보일러플레이트 코드(boilerplate code)보다 훨씬 더 중요하다
    • 비즈니스에 중요한 기능에서 발생한 버그가 가장 큰 피해를 입힌다.

ETC

  • 단순한 코드를 테스트 하는 것은 가치가 거의없다.
    • ex. getter, setter
  • 코드 외에 작성하지 않는 코드(라이브러리, 프레임워크, 외부 시스템)를 테스트 하는것도 중요하다.

회귀 방지 지표를 극대화하려면 테스트가 가능한 한 많은 코드를 실행하는 것을 목표로 해야 한다.

2. 리팩터링 내성

테스트를 실패로 바꾸지 않고 기본 애플리케이션 코드를 리펙터링할 수 있는지에 대한 척도이다.

리팩터링 내성에 대한 평가 사항

  • 거짓 양성의 빈도수(적을수록 좋다.)

테스트가 지속 가능한 성장을 하게 하는 메커니즘은 회귀 없이 주기적으로 리팩터링하고 새로운 기능을 추가하는 것 인데 여기에 대한 장점은 2가지가 있다.

  • 기존 기능이 고장났을 때 테스트가 조기 경고를 제공한다.
    • 조기 경고로 결함이 있는 코드가 운영 환경에 배포되기 전에 문제를 해결할 수 있다.
  • 코드 변경이 회귀로 이어지지 않을 것 이라고 확신하게 된다.
    • 확신이 없다면 리팩터링을 주저하게 되고 코드베이스가 나빠질 가능성이 훨씬 높아진다.

하지만 거짓 양성은 이 두 가지 이점을 모두 방해한다.

  • 테스트가 타당한 이유 없이 실패하면, 코드 문제에 대응하는 능력과 의지가 희적된다.
    • 실패에 익숙 -> 신경 X -> 타당한 실패도 무시
  • 거짓 양성이 빈번하면 테스트 스위트에 대한 신뢰가 떨어져 더 이상 믿을 만한 안정망으로 인식하지 않는다.
    • 신뢰가 줄어듦 -> 리팩토링이 줄어듦 -> 회귀를 피하려 코드 변경을 최소화

거짓 양성의 원인

  • 테스트와 SUT의 구현 세부 사항이 많이 결합할수록 허위 경보가 더 많이 생긴다.
  • 거짓 양성을 줄이는 방법 : 테스트와 구현 세부 상황을 분리한다.

리팩터링 내성를 높이는 방법

  • 코드의 내부 작업과 테스트 사이를 가능 한 멀리 떨어뜨리고 최종 결과를 목표로 한다.