1. 단위 테스트의 목표
- 가치 있는 테스트만 남기고 나머지는 모두 제거하라. 애플리케이션과 테스트 코드는 모두 자산이 아니라 부채다.
- 단위 테스트의 목표는 무엇인가? 소프트웨어 프로젝트의 지속 가능한 성장을 가능하게 하는 것이다. 지속 가능하다는 것이 핵심이다.
- 성공적인 테스트 스위트는 다음과 같다.
- 개발 주기에 통합되어 있다.
- 코드베이스에서 가장 중요한 부분만을 대상으로 한다.
2. 단위 테스트란 무엇인가
- 테스트는 해결하는 데 도움이 되는 문제에 대한 이야기를 들려줘야 하며, 이 이야기는 프로그래머가 아닌 일반 사람들에게 응집도가 높고 의미가 있어야 한다.
- 테스트 대상 단위는 코드 단위가 아니라 동작 단위다. 따라서 공유 의존성만 테스트 대역으로 대체해야 한다.
- 최종 사용자에게 의미 있는 결과만 확인해야 한다. 다른 모든 것은 무시해야 한다.
- 결합도를 낮추려면 테스트는 SUT가 수행한 단계가 아니라 SUT가 만든 최종 결과를 검증해야 한다.
- 테스트는 '어떻게'가 아니라 '무엇'에 중점을 둬야 한다. 그렇다면 구현 세부사항은 정확히 무엇이며 식별할 수 있는 동작과 어떻게 다른가?
- 다음 요구 사항을 하나라도 충족하면 식별할 수 있는 동작이다.
- 클라이언트가 목표를 달성하는데 도움이 되는 연산을 노출하라. 연산은 계산을 수행하거나 부작용을 초래하거나 또는 둘 다 하는 메서드다.
- 클라이언트가 목표를 달성하는데 도움이 되는 상태를 노출하라. 상태는 시스템의 현재 상태다.
- 시스템 내 통신은 구현 세부 사항이다.
애플리케이션을 통해서만 접근할 수 있는 외부 시스템을 제외하고 시스템 간 통신은 식별할 수 있는 동작이다.
애플리케이션을 통해서만 접근할 수 있는 외부 시스템과의 상호 작용도 구현 세부 사항인데, 그 결과의 부작용은 외부에서 확인할 수 없기 때문이다. - 시스템 내 통신을 검증하고자 목을 사용하면 취약한 테스트로 이어진다.
따라서 시스템 간 통신(애플리케이션 경계를 넘는 통신)과 해당 통신의 부작용이 외부 환경에서 보일 때만 목을 사용하는 것이 타당하다.
- 다음 요구 사항을 하나라도 충족하면 식별할 수 있는 동작이다.
- 잘 설계된 코드는 식별할 수 있는 동작이 공개 API와 일치하고 구현 세부 사항이 비공개 API 뒤에 숨겨져 있는 코드다.
3. 단위 테스트 구조
- 모든 단위 테스트는 AAA 패턴(준비, 실행, 검증)을 따라야 한다.
- 단일한 목표를 달성하고자 클래스에서 호출해야 하는 연산의 수가 1보다 크면 해당 클래스에서 구현한 세부사항을 유출할 가능성이 있다.
- 실행 구절이 한 줄 이상이면 SUT의 API에 문제가 있다는 뜻이다.
- 실행 구절을 한 줄로 하는 지침은 비즈니스 로직을 포함하는 대부분 코드에서 적용되지만, 유틸리티나 인프라 코드는 덜 적용된다. 그러므로 절대 두 줄 이상 두 말라고 할 수 없다. 각각의 사에 캡슐화 위반이 있을 수 있는지 살펴보자
- SUT의 이름을 sut로 지정해 SUT를 테스트에서 구별하자.
- 테스트를 수정해도 다른 테스트에 영향을 주어서는 안 된다. 테스트 클래스에 공유 상태를 두지 말아야 한다.
- 테스트 픽스처 초기화 코드는 생성자에 두지 말고 비공개 팩토리 메서드를 도입해서 재사용하자. 이러한 재사용은 테스트 간 결합도를 상당히 낮게 유지하고 가독성을 향상시킨다.
4. 기타
- 리팩토링 내성은 타협할 수 없다. 테스트 스위트를 탄탄하게 만들려면 테스트의 거짓 양성을 제거하는 것이 최우선 과제다.
- 단위 테스트는 알고리즘이나 비즈니스 복잡도가 없는 환경에서는 유용하지 않다.
- 목은 외부로 나가는 상호 작용, 스텁은 내부로 들어오는 상호 작용
- 스파이는 기능적으로 목과 같고, 더미와 페이크는 스텁과 같은 역할을 한다.
출처 - 단위테스트, 생산성과 품질을 위한 단위 테스트 원칙과 패턴
'Develop > Fundmental' 카테고리의 다른 글
메모리 매핑 (Memory-mapped file) (0) | 2022.11.20 |
---|---|
Decorator pattern (데코레이터 패턴) (0) | 2022.05.03 |
Bridge Pattern(브릿지 패턴) (0) | 2022.05.01 |
Adapter Pattern (어댑터 패턴) (0) | 2022.05.01 |
Builder Pattern (빌더 패턴) (0) | 2022.04.28 |
댓글