Table of contents
Open Table of contents
좋은 단위 테스트의 4대 요소
- 좋은 단위 테스트에는 단위 테스트, 통합 테스트, 엔드 투 엔드 테스트 등 자동화된 테스트를 분석하는 데 사용할 수 있는 네 가지 기본 특성이 있다.
- 회귀 방지
- 리팩터링 내성
- 빠른 피드백
- 유지 보수성
회귀 방지
- 회귀 방지는 테스트가 얼마나 버그(회귀)의 존재를 잘 나타내는지에 대한 척도다.
- 테스트가 코드를 더 많이 실행할수록 테스트에서 버그가 드러날 확률이 더 높아진다.
리팩터링 내성
- 리팩터링 내성은 테스트가 거짓 양성을 내지 않고 애플리케이션 코드 리팩터링을 유지할 수 있는 정도를 의미한다.
- 거짓 양성은 허위 경보다. 즉, 테스트가 실패했다고 나타내지만 그 기능은 의도한대로 작동한다.
- 거짓 양성은 테스트 대상 시스템의 내부 구현 세부 사항과 테스트 간의 강결합의 결과다.
- 결합도를 낮추려면 테스트는 SUT가 수행한 단계가 아니라 SUT가 만든 최종 결과를 검증해야 한다.
- 리팩터링 내성은 타협할 수 없다. 테스트에 이 속성이 있는지 여부는 대부분 이진선택, 즉 리팩터링 내성을 갖고 있거나 갖고 있지 않거나 둘 중 하나이기 때문이다.
빠른 피드백
빠른 피드백은 테스트가 얼마나 빨리 실행되는지에 대한 척도다.
유지 보수성
유지 보수성은 두 가지 요소로 구성된다.
- 테스트 이해 난이도, 테스트가 작을수록 읽기 쉽다.
- 테스트 실행 난이도, 테스트에 관련된 프로세스 외부 의존성은 적을수록 쉽게 운영할 수 있다.
테스트를 작성할 떄는 블랙박스 테스트 방법을 사용하라. 테스트를 분석할 때는 화이트박스 방법을 사용하라.
목과 테스트 취약성
- 테스트 대역은 테스트에서 비제품 가짜 의존성의 모든 유형을 설명하는 포괄적인 용어다.
- 테스트 대역에는 더미, 스텁, 스파이, 목, 페이크 등의 다섯 가지 변형이 있는데, 이는 다시 목과 스텁이라는 두 가지 유형으로 분류할 수 있다.
- 스파이는 기능적으로 목과 같고, 더미와 페이크는 스텁과 같은 역할을 한다.
- 명령 조회 분리 원칙에 따르면, 모든 메서드가 명령 또는 조회 중 하나여야 하지만 둘 다는 안 된다.
- 명령을 대체하는 테스트 대역은 목이다. 조회를 대체하는 테스트 대역은 스텁이다.
Mock
- 목은 외부로 나가는 상호작용을 모방하고 검사하는 데 도움이 된다.
Stub
- 스텁은 내부로 들어오는 상호 작용을 모방하는데 도움이 된다.
- 스텁과의 상호 작용을 검증하면 취약한 테스트로 이어진다.
애플리케이션 테스트
헥사고날 아키텍처는 다음과 같은 세 가지 관점을 강조한다.
- 도메인과 애플리케이션 서비스 계층 간의 영향 분리, 도메인 계층은 비즈니스 로직을 책임져야 하고, 애플리케이션 서비스는 도메인 계층과 외부 애플리케이션 간의 작업을 조정해야 한다.
- 애플리케이션 서비스 계층에서 도메인 계층으로의 단반향 의존성 흐름, 도메인 계층 내 클래스는 서로에게만 의존해야 하고, 애플리케이션 서비스 계층의 클래스에 의존해서는 안된다.
- 외부 애플리케이션은 애플리케이션 서비스 계층이 유지하는 공통 인터페이스를 통해 연결된다. 아무도 도메인 계층에 직접 엑세스할 수 없다.
애플리케이션은 시스템 내부 통신과 시스템 간 통신이라는 두 가지 통신 유형이 있다.
- 시스템 내부 통신은 애플리케이션 내 클래스 간의 통신이다.
- 시스템 내 통신은 구현 세부 사항이다. 애플리케이션을 통해서만 접근할 수 있는 외부 시스템을 제외하고 시스템 간 통신은 식별할 수 있는 동작이다.
- 시스템 내 통신을 검증하고자 목을 사용하면 취약한 테스트로 이어진다. 따라서 시스템 간 통신과 해당 통신의 사이드 이펙트가 외부 환경에서 보일 때만 목을 사용하는 것이 타당하다.
단위 테스트 스타일
출력 기반 테스트
- 출력 기반 테스트는 SUT에 입력을 주고 출력을 확인하는 테스트 스타일이다.
- 이 테스트 스타일은 숨은 입출력이 없다고 가정하고, SUT 작업의 결과는 반환하는 값뿐이다.
- 출력 기반 테스트가 테스트 품질이 가장 좋다. 이러한 테스트는 구현 세부 사항에 거의 결합되지 않으므로 리팩터링 내성이 있다.
- 또한 작고 간결하므로 유지 보수 하기도 쉽다.
상태 기반 테스트
- 상태 기반 테스트는 작업이 완료된 후의 시스템의 상태를 확인한다.
- 단위 테스트의 고전파는 통신 기반 스타일보다 상태 기반 스타일을 선호 한다.
- 상태 기반 테스트는 테스트 안정성을 위해 더 신중해야 한다.
- 단위 테스트를 하려면 비공개 상태를 노출하지 않도록 해야 한다.
통신 기반 테스트
- 통신 기반 테스트는 목을 사용해서 테스트 대상 시스템과 협력자 간의 통신을 검증한다.
- 통신 기반 테스트는 안정성을 위해 더 신중해야 한다.
- 애플리케이션의 경계를 넘어서 외부 환경에 사이드 이펙트가 보이는 통신만 확인해야 한다.