3장 - 단위 테스트 구조
3장에서 다루는 내용
- 단위 테스트 구조
- 좋은 단위 테스트 명명법
- 매개변수화된 테스트 작성
AAA 패턴
AAA 패턴은 준비, 실행, 검증 부분으로 나누어 테스트를 작성합니다.
흔히 알고 있는 given, when, then 패턴과 굉장히 유사합니다.
여러 개의 준비, 실행, 구절 피하기
때로는 준비 -> 실행 -> 검증 -> 좀 더 실행 -> 다시 검증과 같은 테스트를 만날 수 있습니다.
실제로 종종 이런 테스트구조를 만들곤 했으며 여러 테스트는 오히려 soft copy처럼 보이고 귀찮으니..
하지만 이렇게 되면 더 이상 단위 테스트가 아닌 통합 테스트입니다.
일련의 실행과 검증이 포함된 테스트를 보면 각 동작은 고유한 테스트로 분리하는 것이 좋습니다.
테스트 내 if문 피하기
if문이 발생하는것 자체가 안티 패턴으로 이는 테스트가 한 번에 너무 많은 것을 검증한다는 표시입니다.
각 구절의 길이
일반적으로 givne(준비) 구절이 가장 큽니다.
너무 크면 private 메서드나 별도의 팩토리 클래스로 도출하는 것도 좋습니다.
when(실행 구절)은 일반적으로 한 줄입니다.
실행 구절이 두줄 이상인 경우는 캡슐화가 깨져있다는 신호일 수 있습니다.
해결책으로는 코드를 리팩터링 하여 불변 위반을 초래할 수 있는 잠재적인 행동을 제거하는 것입니다.
then(검증 구절)은 너무 커지는것만 경계하며 하나의 테스트로 그 모든 결과를 평가하는 것이 좋습니다.
end(종료 단계)로 간혹 분리하기도 합니다.
예를 들면 테스트에 의해 작성된 파일이나 데이터베이스를 cleanUp 하는 과정입니다.
단위 테스트는 프로세스 외부에 종속적이지 않으므로 종료는 대게 통합 테스트의 영역입니다.
테스트 간 테스트 픽스처 재사용
준비 구절에서 코드를 재사용하는 것이 테스트를 줄이면서 단순화하기 가장 좋은 방법입니다.
반복되는 준비구절은 개발자를 지치게합니다.
예를 들어 BeforeEach 등으로 공통된 로직을 추출할 수 있습니다.
하지만 테스트 간 결합도가 높아지며, 테스트 가독성이 떨어지는 단점이 발생합니다.
이는 안티 패턴으로 테스트의 독립적인 수정을 불가능하게 합니다.
이보다는 private factory method도 추출하여 테스트 코드를 짧게 하며 테스트 가독성도 높일 수 있습니다.
단위 테스트 명명법
가장 유명하지만 가장 도움이 되지 않는 방법 중 하나는 다음과 같은 관습입니다.
[테스트 대상 메서드]_[시나리오]_[예상 결과]
예를 들어 sum_of_two_number를 위의 관습을 따르게 되면 sum_TwoNumbers_ReturnsSum이 됩니다.
엄격한 명명정책을 따르지 않고, 비개발자들에게 시나리오를 설명하는 것처럼 테스트 이름을 짓자.
저는 코틀린에서 한글을 사용해서 다음과 같이 명명하곤 했습니다.
fun `존재하는 회원의 닉네임을 update할 때 닉네임이 중복된다면 unique 제약조건에 의해 DataIntegrityViolationException 발생한다`()
하지만 뒤의 예외의 이름까지 명시하는 것은 너무 구체적이며, 비개발자들이 이해할 수 없을 것 같습니다.
예외가 발생한다 정도로 표기하면 좋을 것 같습니다.
검증문 라이브러리로 테스트 가독성 향상
Assert.Equals보단 should be가 더 쉬운 영어이고 가독성이 높습니다.