단위 테스트의 정의
1.
작은 코드 단위를 테스트,
2.
빠르게 수행하고,
3.
격리된 방식으로 처리하는 자동화된 테스트
격리가 무엇인지에 대한 의견 차이가 디트로이트 학파와 런던 학파를 나눈다.
격리에 대한 의견 차이는 테스트 단위에 대한 차이로 이어진다.
런던 학파
테스트 대상 시스템을 협력자에서 격리하는 것 ⇒ 테스트 대상 클래스의 모든 의존성을 테스트 대역(test double)로 대체해야 한다. ⇒ 장점 : 테스트가 실패하면 어디가 고장난건지 확실히 알 수 있다, 객체 그래프(객체 사이의 의존성을 그래프로 그린 것)을 중간에 끊어내고 테스트를 더 간단하게 할 수 있다.
단위 = 단일 클래스
테스트 대역 = 불변 의존성 제외한 모든 의존성
디트로이트 학파
단위 테스트를 격리하는 것 ⇒ 공유 의존성을 데스트 대역으로 대체하는 것
공유 의존성 : 테스트 간에 공유되고 서로의 결과에 영향을 미칠 수 있는 수단을 제공하는 의존성. 정적 가변 필드, 데이터베이스 등이 이에 해당된다.
비공개 의존성 : 공유하지 않는 의존성
프로세스 외부 의존성 : 애플리케이션 실행 프로세스 외부에서 실행되는 의존성. 보통은 공유 의존성이나, 꼭 공유 의존성인 것은 아니다. 예를 들어 데이터베이스는 프로세스 외부 의존성이지만, 테스트마다 컨테이너를 이용해 다른 데이터베이스를 실행시킨다면 공유 의존성은 아니다.
단위 = 공유 의존성이 없는 여러 클래스의 모음 혹은 단일 클래스
테스트 대역 = 공유 의존성
런던 학파 장점
1.
테스트가 한번에 한 클래스만 확인한다. 즉, 원자성이 높다.
2.
테스트가 깨졌을 때, 테스트 대상 클래스의 문제인 것이 확실해진다. 의존이 모두 테스트 더블이기 때문
3.
테스트 코드에서 테스트를 위한 준비 과정이 비교적 짧아진다. 의존성의 의존성의 의존성.. 등 의존성 체인을 고려할 필요가 없기 때문이다.
런던 학파 장점에 대한 고전 학파의 반박
테스트가 한번에 한 클래스만 확인한다. 즉, 원자성이 높다.
테스트가 확인해야 하는 것은 코드 단위가 아니라, 어떤 동작 단위이다. 즉, 클래스나 메서드 단위로 원자성이 보장되는 테스트는 지나치게 세부 사항으로 바라보게 한다. (개가 주인에게 온다. vs 개가 앞발을 들고 뒷발을 들고…)
테스트는 프로그래머 뿐 아니라, 일반 이해관계자에게도 의미가 있어야 한다. (왜?)
테스트 코드에서 테스트를 위한 준비 과정이 비교적 짧아진다. 의존성의 의존성의 의존성.. 등 의존성 체인(객체 그래프)을 고려할 필요가 없기 때문이다.
맞는 말이다. 하지만, 접근 방법에 문제가 있다. 크고 복잡하게 얽힌 것을 쉽게 테스트 할 방법을 찾는게 아니라, 애초에 이렇게 크고 복잡하게 얽힌 것이 잘못된 설계임에 주목해야 한다.
테스트에서 테스트 대상(SUT)의 설계가 잘못되었음을 지적하는 것은 좋은 일이 아닌가?
목을 사용하면 지금 설계가 잘못된 설계임을 감추기만 할 뿐이다.
테스트가 깨졌을 때, 테스트 대상 클래스의 문제인 것이 확실해진다. 의존이 모두 테스트 더블이기 때문
하나의 버그가 전체 시스템에 걸쳐 테스트 실패를 야기하면, 정확한 원인을 찾기 힘들 . 수있다는 것에는 동의한다. 하지만, 이는 잦은 테스트 실행( 이상적으로는 코드가 변경될 . 때마다 테스트를 수행하는 것이 좋다.)을 통해 예방할 . 수있다. 마지막으로 수정한 코드가 원인일 것이기 때문.
오히려, 테스트가 계단식으로 실패하는 것이 가치가 있다. 어떤 버그가 여러 테스트를 실패하게 한다면, 방금 고장나게 한 코드 조각을 많은 곳에서 의존하고 있다는 것을 보여주는 것이기 때문이다. 이런 정보는 상당히 유용한 정보다.
두 분파의 통합 테스트에 대한 차이
런던 학파에서는 통합 테스트는 실제 의존성을 사용하면 모두 통합 테스트로 간주한다.
고전적으로 통합 테스트는 단위테스트의 조건 중 하나 이상 충족하지 않는 테스트다.
즉, 통합 테스트는 공유 의존성, 프로세스 외부 의존성에 대해 함께 테스트 한다.
엔드 투 엔드 테스트는 좀 더 많은 외부 의존성을 포함해 테스트 하는 것이다.