Unit 테스트 정리
Enterprise Application에는 거의 모두 단위 테스트가 적용돼 있다. 제품 코드와 테스트 코드의 비율은 1:1에서 1:3정도 된다. 때로는 그 비율이 1:10 수준에 이르기도 한다.
좋은 단위 테스트를 작성하는 것은 어떤 의미인가?
단위 테스트의 목표는 프로젝트의 지속 가능한 성장이다.
테스트 유무에 따른 프로젝트간 성장 추이의 차이. 테스트가 없는 프로젝트의 경우 시작은 유리하지만 이내 진척이 없을 정도로 느려진다. 개발 속도가 빠르게 감소하는 이러한 현상을 소프트웨어 엔트로피라고도 한다. 엔트로피(시스템 내 무질서도)
코드서 무언가를 변경할 때마다 무질서도(엔트로피)는 증가한다. 지속적인 정리와 리팩터링 등과 같은 적절한 관리를 하지 않고 방치하면 시스템이 점점 더 복잡해지고 무질서해진다. 하나 의 버그를 수정하면 더 많은 버그를 양상한고, 소프트웨어의 한 부분을 수정하면 다른 부분들이 고장난다.
테스트는 안정망 역할을 하며, 대부분의 회귀에 대한 보험을 제공하는 도구다. 테스트는 새로운 기능을 도입하거나 새로운 요구사항에 더 잘 맞게 리팩토링한 후에도 기존 기능이 잘 작동하는지 확인하는데 도움을 준다.
코드는 자산이 아니라 책임이다. 코드가 더 많아질수록, 소프트웨어 내의 잠재적인 버그에 노출되는 표면적이 더 넓어지고 프로젝트 유지비가 증가한다. 따라서 가능한 한 적은 코드로 문제를 해결하는 것이 좋다.
테스트도 코드이다. 특정 문제를 해결하는 것. 즉 애플리케이션의 정확성을 보장하는 것을 목표로하는 코드베이스의 일부로 봐야한다. 다른 코드와 마찬가지로 단위 테스트도 버그에 취약하고 유지 보수가 필요하다.
테스트 커버리지는 지표 그 자체로 보고, 목표로 여기지 말자.
유지비를 상회하는 테스트만 스위트에 작성하는 것이 중요하다.
테스는 코드의 단위를 검증해서는 안된다. 오히려 동작의 단위, 즉 문제 영역에 의미가 있는 것. 이상적으로는 비즈니스 담당자가 유용하다고 인식할 수 있는 것을 검증해야한다.
통합 테스트와 E2E의 경계가 가끔 흐려지지만, 일반적으로 통합 테스트는 프로세스 외부 의존성을 한두 개만 갖고 작동한다. 반면에 엔드 투 엔드 테스트는 프로세스 외부 의존성을 전부 또는 대다수 갖고 작동한다. 따라서 엔드 투 엔드라는 명칭은 모든 외부 애플리케이션을 포함해 시스템을 최종 사용자 관점에서 검증하는 것을 의미한다.
통합 테스트와 엔드 투 엔드 테스트 간의 뚜렷한 경계는 존재하지 않는다.
런던파는 테스트 대상 단위를 서로 분리해야 한다고 한다. 테스트 대상 단위는 코드의 단위, 보통 단일 클래스이다. 불변 의존성을 제외한 모든 의존성을 테스트 목으로 대체해야한다.
고전파는 단위가 아니라 단위 테스트를 서로 분리해야한다고 한다. 또한 테스트 대상 단위는 코드 단위가 아니라 동작 단위이다. 따라서 공유 의존성만 테스트 대역으로 대체해야한다. 공유 의존성은 테스트가 서로 실행 흐름에 영향을 미치는 수단을 제공하는 의존성이다.
통합 테스트에서는 실행 구절을 여러개 두는 것이 괜찮을 때도 있다. 통합 테스트는 느릴 수 있는데 속도를 높이는 한 가지 방법은 여러 개의 통합 테스트를 여러 실행과 검증이 있는 단일한 테스트로 묶는 것이다. 시스템 상태의 흐름이 자연스럽다면, 즉 실행이 동시에 후속 실행을 위한 준비로 제공될 때 특히 유용하다. 이 최적화 기법은 통합 테스트에만 적용할 수 있다. 그것도, 전부가 아니라 이미 느리고 더 느려지게 하고 싶지 않은 테스트들만이다. 단위 테스트나 충분히 빠른 통합 테스트에서는 이러한 최적화가 필요하지 않다. 항상 다단계 단위 테스트를 여러개의 테스트로 나누는 것이 더 좋다.
모든 테스트는 AAA(준비, 실행, 검증) 패턴을 따라야 한다. 테스트 내 준비나 실행 또는 검증 구절이 여러개 있으면 테스트가 여러 동작 단위를 한 번에 검증한다는 표시다. 이 테스트가 단위 테스트라면 각 동작에 하나씩 여러 개의 테스트로 나눠야 한다.
실행 구절이 한 줄 이상이면 SUT의 API에 문제가 있다는 뜻이다. 클라이언트가 항상 이러한 작업을 같이 수행해야하고, 이로 인해 잠재적으로 모순으로 이어질 수 있다. 이러한 못순을 불변 위반이라고 한다. 잠재적인 불변 위반 으로부터 코드를보호하는 것을 캡슐화라고 한다.