요약
- 모든 단위 테스트는 AAA(준비, 실행, 검증) 구조를 따라야 한다.
- 실행 구절이 한 줄 이상이면 SUT의 API에 문제가 있다는 뜻이다. 항상 여러줄의 코드가 묶여서 실행되어야 하고, 한 줄이라도 빠질 경우 동작에 모순이 생긴다. 이를 불변 위반이라고 한다.
- 불변 위반으로부터 코드를 보호하는 것을 캡슐화라고 한다.
- 테스트 픽스처 초기화 코드는 팩토리 메서드를 사용하자. 이러한 재사용은 테스트 간 결합도를 낮게 유지하고 가독성을 향상 시킨다.
- 문제 도메인에 익숙한 비개발자들에게 시나리오를 설명하는 것처럼 각 테스트의 이름을 지정하자.
단위 테스트를 구성하는 방법
-
AAA 패턴
- 각 테스트를 준비, 실행, 검증 부분으로 나눈다.
-
given-when-then 과 유사한 패턴. 테스트 구성 측면에서 두 패턴 사이의 차이는 없다.
- 준비 : 테스트 대상 시스템(SUT)과 해당 의존성을 원하는 상태로 만든다.
- 실행 : SUT에서 메서드를 호출하고 준비된 의존서을 전달하며 출력 값을 캡처한다.
- 검증 : 결과를 검증한다.
-
하나의 테스트에서 하나의 동작만 검증하기
- 여러 개의 실행 구문 == 여러 개의 동작 단위를 검증하는 테스트를 뜻한다. -> 단위 테스트가 아니라 통합 테스트! 이러한 단위 테스트 구조는 피하는 것이 좋다.
- 각 동작을 고유의 테스트로 도출하라.
- if 문은 테스트가 한 번에 너무 많을 것을 검증한다는 표시다.
-
준비 구절
- 준비 구절이 보통 세 구절 중 가장 크다.
- 오브젝트 마더, 테스트 데이터 빌더를 활용하여 준비 구절 코드를 재사용 할 수 있다.
-
실행 구절
- 실행 구절이 한 줄 이상인 경우를 경계하라.
- 실행 구절이 여러 줄인 경우 == 캡슐화가 깨진 경우
- 클라이언트에게 메서드 호출을 더 강요해서는 안된다.
-
불변 위반
- 클라이언트 코드가 첫 번째 메서드는 호출하고 두 번째 메서드를 호출하지 않을 때 모순이 생긴다.
- 잠재적인 모순으로부터 코드를 보호하는 행위를 캡슐화라고 한다.
- 캡슐화를 항상 지켜야 한다.
-
검증 구절
- 단위 테스트의 단위는 동작의 단위이지 코드의 단위가 아니다. -> 단일 동작 단위는 여러 결과를 낼 수 있으며, 하나의 테스트로 그 결과를 평사하는 것이 좋다.
- 그렇기는 해도 검증 구절이 너무 커지는 것은 경계해야 한다.
각 테스트는 이야기가 있어야 한다.
- 문제 영역에 대한 개별적이고 원자적인 사실이다 시나리오
- 테스트가 통과하는 것은 이 사실 또는 시나리오가 실제 사실이라는 증거
- 테스트가 실패하면 이야기가 더 이상 유효하지 않아 테스트를 다시 작성해야 하거나 시스템 자체를 수정해야 한다.
- 테스트가 제품 코드의 기능을 무조건 나열하면 안 된다. 애플리케이션의 동작에 대해 고수준의 명세가 있어야 한다.
테스트 픽스처 재사용
- 테스트 픽스처 : 테스트의 실행 대상 객체
-
테스트의 생성자에서 테스트 픽스처를 초기화하여 각 테스트에서 재사용하는 방법
- 테스트 간 결합도가 높아진다. -> 테스트 간의 높은 결합도는 안티 패턴이다.
- 테스트 가독성이 떨어진다. -> 테스트만 보고는 더 이상 전체 그림을 볼 수 없다.
- 테스트 클래스에 비공개 팩토리 메서드를 두어 각 테스트에서 생성하여 사용하는 방법
단위 테스트 명명 지침
- 엄격한 명명 정책을 따르지 않는다. 복잡한 동작에 대한 높은 수준의 설명은 정책을 따를 수 없는 경우가 많다.
- 문제 도메인에 익숙한 비개발자들에게 설명하는 것처럼 테스트 이름을 짓자.
- 단위 테스트에서 단위는 동작의 단위이지 클래스틔 단위가 아닌 것을 명심하자.