Folders and files Name Name Last commit message
Last commit date
parent directory
View all files
테스트는 시스템의 일부이며, 아키텍처에도 관여함
테스트에 관련한 상당한 혼동
테스트는 시스템의 일부인가? 아니면 별개인가?
어떤 종류의 테스트가 있는가?
단위 테스트와 통합 테스트는 서로 다른가?
인수 테스트, 기능 테스트, Cucumber 테스트, TDD 테스트, BDD 테스트, 컴포넌트 테스트 등은 어떻지?
아키텍처 관점에서는 모든 테스트가 동일함
테스트는 태생적으로 의존성 규칙을 따름
테스트는 세부적이며 구체적인 것으로, 의존성은 항상 테스트 대상이 되는 코드를 향함
실제로 테스트는 아키텍처에서 가장 바깥쪽 원으로 생각할 수 있음
시스템 내부의 어떤 것도 테스트에는 의존하지 않으며, 테스트는 시스템의 컴포넌트를 향해, 항상 원의 안쪽으로 의존함
테스트는 독립적으로 배포 가능함
사실 대다수의 경우 테스트는 테스트 시스템에만 배포하며, 상용 시스템에는 배포하지 않음
심지어 배포 독립성이 달리 필요하지 않은 시스템에서도 테스트는 독립적으로 배포될 것
테스트는 시스템 컴포넌트 중에서 가장 고립되어 있음
테스트가 시스템 운영에 꼭 필요치는 않음
어떤 사용자도 테스트에 의존하지 않음
테스트의 역할은 운영이 아니라 개발을 지원하는 데 있음
그렇다고 해서 테스트가 시스템의 컴포넌트가 아니란 뜻은 아님
사실 많은 면에서 테스트는 다른 모든 시스템 컴포넌트가 반드시 지켜야 하는 모델을 표현해줌
개발자는 종종 테스트가 시스템의 설계 범위 밖에 있다고 여기지만, 이 관점은 치명적
테스트가 시스템 설계와 잘 통합되지 않으면, 테스트는 깨지기 쉬워지고, 시스템은 뻣뻣해져서 변경하기가 어려워짐
문제는 결합
시스템에 강하게 결합되 테스트라면, 시스템이 변경될 때 함께 변경되어야만 함
시스템 컴포넌트에서 생긴 아주 사소한 변경도, 이와 결합된 수많은 테스트를 망가뜨릴 수 있음
깨지기 쉬운 테스트 문제가 수천 개정도 되면 상황은 더 심각해질 수 있음
깨지기 쉬운 테스트는 시스템을 뻣뻣하게 만든다는 부작용을 낳을 때가 많음
시스템에 가한 간단한 변경이 대량의 테스트 실패로 이어진다는 사실을 알게 되면, 개발자는 그러한 변경을 하지 않으려 들 것
이 문제를 해결하려면 테스트를 고려해서 설계해야 함
소프트웨어 설계의 첫 번째 규칙은 언제나 같다.
따라서 시스템과 테스트를 설계할 때 업무 규칙을 테스트할 수 있게 해야 함
이 목표를 달성하려면 테스트가 모든 업무 규칙을 검증하는 데 사용할 수 있도록 특화된 API 를 만들면 됨
이러한 API 는 보안 제약사항을 무시할 수 있으며, 데이터베이스와 같은 값비싼 자원은 건너뛰고, 시스템을 테스트 가능한 특정 상태로 강제하는 강력한 힘을 지녀야만 함
이 API 는 사용자 인터페이스가 사용하는 인터렉터와 인터페이스 어댑터들의 상위 집합이 될 것
테스트 API 는 테스트를 애플리케이션으로부터 분리할 목적으로 사용함
그리고 테스트 구조를 애플리케이션 구조로부터 결합을 분리하는 게 목표
구조적 결합은 테스트 결합 중에서 가장 강하며, 가장 은밀하게 퍼져 나가는 유형
모든 사용 클래스에 테스트 클래스가 각각 존재하고, 또 모든 사용 메서드에 테스트 메서드 집합이 각각 존재하는 테스트 스위트가 있다고 가정해보자
이러한 테스트 스위트는 애플리케이션 구조에 강하게 결합되어 있음
테스트 API 의 역할은 애플리케이션 구조를 테스트로부터 숨기는 데 있음
이렇게 만들면 상용 코드를 리팩터링 하거나 진화시키더라도 테스트에는 전혀 영향을 주지 않음
또한 테스트를 리팩터링하거나 진화시킬 때도 상용 코드에는 전혀 영향을 주지 않음
이처럼 따로따로 진화할 수 있다는 점은 필수적임
시간이 지날수록 테스트는 계속해서 더 구체적으로 더 특화된 형태로 변할 것이고
반대로 상용 코드는 더 추상적으로 더 범용적인 형태로 변할 것이기 때문
하지만 조직 결합이 더 강하면 필수적인 진화 과정을 방해하거나 지연시킬 뿐만 아니라, 상용 코드의 범용성과 유연성이 충분히 좋아지지 못하게 막음
테스트 API 가 지닌 강력한 힘을 운영 시스템에 배포하면 위험에 처할 수 있음
위험을 피하고 싶다면, 테스트 API 자체와 테스트 API 중 위험한 부분의 구현부는 독립적으로 배포할 수 있는 컴포넌트로 분리해야 함
테스트는 시스템 외부에 있지 않음, 오히려 시스템의 일부
따라서 테스트에서 기대하는 안정성과 회귀의 이점을 얻을 수 있으려면 테스트는 잘 설계돼야만 함
테스트를 잘 설계하면, 깨지기 쉬워지지 않고, 유지보수하기 쉬워져 지속적으로 개발 가능해짐
You can’t perform that action at this time.