요약
-
좋은 단위 테스트의 4가지 특성
- 회귀 방지 : 테스트가 얼마나 버그(회귀)의 존재를 잘 나타내는지에 대한 척도.
-
리팩터링 내성 : 테스트가 거짓 양성을 내지 않고 애플리케이션 코드 리팩터링을 유지할 수 있는 정도
- 거짓 양성 == 허위 경보
-
거짓 양성은 테스트 스위트에 치명적인 영향을 줄 수 있다.
- 테스트를 신뢰할 수 있는 안전망으로 인식하는 것이 줄어들고 테스트 스위트에 대한 신뢰를 잃게 된다.
- 거짓 양성은 테스트 대상 시스템의 내부 구현 세부 사항과 테스트 간의 강결합의 결과다. 결합도를 낮추려면 테스트는 SUT가 수행한 단계각 아니라 SUT가 만든 결과에 검증해야 한다.
- 거짓 양성은 프로젝트 초기에 부정적인 영향을 미치지는 않지만 프로젝트가 성장함에 따라 점점 더 중요해진다. 즉, 거짓 음성(알려지지 않은 버그)만큼 중요하다.
- 빠른 피드백 : 테스트가 얼마나 빠르게 실행되는지에 대한 척도
-
유지 보수성
- 테스트 이해 난이도 : 테스트가 작을수록 읽기 쉽다.
- 테스트 실행 난이도 : 테스트에 관련된 프로세스 외부 의존성은 적을수록 쉽게 운영할 수 있다.
- 회귀 방지와 리팩터링 내성은 테스트 정확도에 기여한다.
- 테스트의 가치 추정치는 네 가지 특성 각각에서 얻은 점수의 곱이다. 따라서 특성 중 하나라도 0이면, 테스트 가치도 0이 된다.
- 회귀 방지, 리팩터링 내성, 빠른 피드백은 상호 배타적이기 때문에 네 가지 특성 모두 최대 점수를 받는 것은 불가능 하다.
- 리팩터링 내성은 타협할 수 없다.
- 테스트는 리팩터링 내성이 있거나 아예 없기 때문에 화이트박스 테스트 대신에 블랙박스 테스트를 기본으로 선택해야 한다.
좋은 단위 테스트의 4대 요소 자세히 살펴보기
- 가치 있는 테스트를 작성하려면 가치 있는 테스트를 식별할 수 있어야 한다.
-
좋은 단위 테스트의 4가지 특성
- 회귀 방지
- 리팩터링 내성
- 빠른 피드백
- 유지 보수성
회귀 방지
-
회귀 == 소프트웨어 버그. 코드를 수정한 후 기능이 의도한 대로 작동하지 않는 경우
- 코드베이스가 커질수록 잠재적인 버그에 더 많이 노출된다.
- 때문에 회귀에 대해 효과적인 보호를 개발하는 것이 중요하다. 이러한 보호가 없다면 프로젝트가 오랫동안 성장할 수 없으며 점점 더 많은 버그가 쌓일 것이다.
-
회귀 방지 지표에 대한 테스트 점수가 얼마나 잘 나오는지 평가하려면 다음 사항을 고려해야 한다.
- 테스트 중에 실행되는 코드의 양 -> 일반적으로 실행되는 코드의 양이 많을수록 테스트에서 회귀가 나타날 가능성이 높다.
- 코드 복잡도
-
코드의 도메인 유의성
- 복잡한 비즈니스 로직을 나타내는 코드가 보일러플레이트 코드보다 훨씬 더 중요하다. 비즈니스에 중요한 기능에서 발생한 버그가 가장 큰 피해를 입히기 때문이다.
리팩터링 내성
-
테스트 실패를 발생하지 않고 기본 애플리케이션 코드를 리팩터링할 수 있는지에 대한 척도
- 기반 코드를 수정하면(리팩터링) 테스트가 빨간색으로 바뀌게끔 작성된 테스트 -> 거짓 양성 (== 허위경보)
- 거짓 양성은 일반적으로 코드를 리팩터링할 때, 즉 구현을 수정하지만 식별할 수 있는 동작은 유지할 때 발생한다.
-
거짓 양성은 테스트 스위트에 치명적인 영향을 줄 수 있다.
- 거짓 양성은 테스트가 프로젝트 성장을 지속 가능하게 하는 것을 방해한다.
- 단위 테스트의 목표는 프로젝트 성장을 지속 가능하게 하는 것 -> 테스트가 지속 가능한 성장을 하게 하는 매커니즘은 회귀 없이 주기적으로 리팩터링하고 새로운 기능을 추가할 수 있는 것이다.
- 허위 경보로 인해 테스트에 대한 신뢰가 부족해지면서 리팩터링이 줄어든다. 회귀를 피하려고 코드 변경을 최소한으로 하기 때문이다. (리팩터링에 대한 능력과 의지를 방해)
-
거짓 양성의 원인
- 테스트 구성 방식과 직접적인 관련이 있다.
- 테스트와 테스트 대상 시스템(SUT)의 구현 세부 사항이 많이 결합할수록 허위 경보가 더 많이 생긴다. -> 리팩터링 내성이 없다.
- 테스트는 최종 사용자의 관점에서 SUT를 검증해야 하고 최종 사용자에게 의미 있는 결과만 확인해야 한다.
- 좋지 않은 거짓 양성은 컴파일 오류를 내지 않는 것이다. 이러한 거짓 양성은 처리하기가 까다롭다.
회귀 방지 특성과 리팩터링 내성 특성 간의 관계
- 테스트 스위트의 정확도를 극대화하는 것을 목표로 한다.
-
정확도 지표의 구성
- 테스트가 버그 있음을 얼마나 잘 나타내는가
- 테스트가 버그 없음을 얼마나 잘 나타내는가
- 테스트의 정확도 = 신호(발견된 버그의 수) / 소음(허위 경보의 발생 수) -> 가능한 한 소음이 적은 강한 신호를 생성하면 테스트가 정확해진다.
- 거짓 양성(허위 경보)은 초기에 그다지 부정적인 영향을 미치지 않는다. 그러나 프로젝트에 거짓 음성(알려지지 않은 버그)이 중요한 만큼 거짓 양성도 점점 중요해진다.
- 시간이 흐를수록 코드베이스는 나빠진다. 점점 복잡해지고 체계적이지 않게 된다. 따라서 이러한 경향을 줄이려면 정기적으로 리팩터링을 해야 한다.
빠른 피드백과 유지 보수성
-
빠른 피드백은 단위 테스트의 필수 속성 -> 테스트 속도가 빠를 수록 테스트 스위트에서 더 많은 테스트를 수행할 수 있고 더 자주 실행할 수 있다.
- 오래 걸리는 테스트는 자주 실행하지 못하기 때문에 잘못된 방향으로 가면서 시간을 더 많이 낭비하게 된다.
-
유지 보수성
- 테스트가 얼마나 이해하기 어려운가? 테스트가 얼마나 실행하기 어려운가? 요소로 구성된다.
이상적인 테스트
- 네 가지 특성을 곱해서 테스트의 가치가 결정된다.
- 회귀 방지, 리팩터링 내성, 빠른 피드백은 상호 배타적이기 때문에 세 가지 특성 모두 최대로 하는 것은 불가능하다.
- 리팩터링 내성은 포기할 수 없다. 이진 선택이기 때문
블랙박스 테스트와 화이트박스 테스트
- 블랙박스 테스트 : 시스템 내부 구조를 몰라도 시스템의 기능을 검사할 수 있는 소프트웨어 테스트 방법 -> 애플리케이션이 무엇을 해야 하는지를 중심으로 구축된다.
- 화이트박스 테스트 : 애플리케이션의 애부 작업을 검증하는 테스트 방식.