시스템을 테스트하려면 부작용을 분리하십시오 .

테스트 가능한 코드를 작성하는 가장 좋은 방법 중 하나는 부작용을 취하는 것입니다

두 남자 전투기 사이의 권투 경기의 그림. 그들의 얼굴은 프레임 바깥에 있습니다. 왼쪽의 전투기가 오른쪽의 전투기에 왼쪽 갈고리를 파견했습니다. 오른쪽의 전투기는 소련의 작은 상징으로 빨간 반바지를 입고 있습니다.

Nock은 네트워크 요청을 스텁하는 데 유용한 JavaScript로 작성된 유명한 라이브러리입니다. HTTP 서버를 사용할 수없는 경우에도 실행할 수 있도록 테스트에 대한 정적 응답을 리턴합니다.

그러나 그것은 또한 냄새입니다.

데이터 소스와 테스트 대상 시스템 간의 결과 커플 링은 코드 리팩토링 및 유지 관리에 영향을 줄 수있는 비용입니다.

이유는 다음과 같습니다.

게시물 목록을 반환하는 서버와 게시물 제목 목록을 만들기 위해 해당 서버의 응답을 사용하는 함수가 있다고 가정 해 봅시다. 함수 테스트는 Nock를 사용하여 서버의 응답을 스텁합니다.

캡션

코드는 괜찮은 범위를 가지고 있습니다. 그러나 몇 가지 문제가 있습니다.

응답의 컨텐츠 유형을 변경하는 경우 코드 동작이 동일하게 유지되는 경우에도 테스트를 변경해야합니다.

Nock가 스터 빙하는 URL, 헤더 또는 매개 변수를 변경하는 경우에도 동일하게 적용됩니다. 시스템의 동작이 동일하게 유지 되더라도 테스트를 변경해야합니다.

"게시물 목록 작성"기능은 테스트 대상 시스템 (SUT)입니다. HTTP 호출의 데이터는 데이터 소스입니다.

데이터 소스가 SUT에 플러그 가능한 일반 인터페이스를 갖도록 코드를 설계 할 수 있습니다. 이 경우 너무 많은 설정이 없어도 로직을 실행할 수 있습니다.

왼쪽에“게시물 목록”캡션이있는 블록을 보여주는 다이어그램. 하나의 화살표는“메모리 내 데이터 소스”캡션이있는 블록을 가리 킵니다. 다른 화살표는“HTTP 서버 데이터”캡션이있는 블록을 가리 킵니다. 출처.

테스트 환경에서는 "메모리 내 데이터 소스"를 삽입 할 수 있습니다. 프로덕션 환경에서는 "HTTP 서버 데이터 소스"를 사용할 수 있습니다.

이전 JSFiddle의 "일반 인터페이스"는 "게시물 제목 찾기"방법입니다. 인터페이스 구축 방법에 관계없이 모든 발신자를 제어 할 수 있습니다. 따라서 변경이 간단합니다. Martin Fowler는이를 "게시되지 않은 인터페이스"라고합니다.

반면에 서버가 게시 된 인터페이스의 계약을 위반하는 경우 클래스 속성이 게시물 제목에서 기사 제목으로 변경되면 데이터 소스 구현 만 변경하면됩니다. 어디서나 변경할 필요가 없습니다.

테스트에 중요하고 조기 피드백을받는 것은 데이터가 아닌 동작에 대한 테스트입니다. 따라서 논리 변경에 필요한 노력을 줄이기 위해 코드를 설계하는 것이 중요합니다. 이 경우 논리는 입력을 데이터 소스에서 HTML 비 순차 목록으로 변환하는 것입니다.

새로운 디자인으로 테스트 대상 시스템에서 데이터 소스를 분리했습니다. 따라서 Nock를 제거 할 수 있습니다.

새로운 디자인은 또한 복사 / 붙여 넣기없이 시스템에 새로운 규칙을 추가하는 데 필요한 작업을 줄입니다.

여전히 "HTTP 서버 데이터 소스"는 개인 함수 "html의 게시물 제목 조회"에 테스트되지 않은 일부 로직이 있습니다.

이를 테스트하기 위해 동일한 패턴을 반복 할 수 있습니다. 부작용을 푸시하고 "요청 받기"메커니즘을 "HTTP 서버 데이터 소스"에 연결 가능하게하십시오. 이런 식으로 Nock 없이도 코드를 테스트 할 수 있습니다.

"포스트 제목 목록"이 "메모리 내 데이터 소스"와 작동하는지 확인하기위한 테스트가 이미 완료된 경우 데이터 소스를 테스트하여 올바른 결과를 리턴하도록 결정할 수 있습니다.

부작용을 논리 밖으로 완전히 밀어 냈습니다. 이 경우 실제 "요청 받기"기능은 부작용입니다. 이제 Nock를 사용하여이를 처리 할 수 ​​있습니다.

그러나 "요청 받기"내부의 논리가 사소하고 비용이 많이 들기 때문에 부작용을 포함하여 전체 응용 프로그램을 실행할 수있는 적은 수의 통합 테스트를 수행하는 것이 좋습니다. Nock를 사용하여 라이브 서버에 대한 연결을 피할 수는 있지만 HTTP 요청을 사용하여 모든 부분이 함께 맞춰지면 응용 프로그램이 합리적인 응답을 반환하는지 확인할 수 있습니다.

Nock는 HTTP 계층에서 연결을 스텁하고 정적 응답을 제공하는 데 유용합니다. 그러나 드물게 사용하십시오. 스터브 할 때마다 상당한 커플 링과 변경 비용이 증가합니다.

드물게 사용하지 않으면 Nock은 Nock Hell을 만들 수 있습니다.

해결하려는 문제는 버그 수와 변경 비용을 줄이는 것입니다. 동작을 변경하지 않고 코드 구조를 변경하면 테스트가 중단되지 않습니다. 그렇다면, 당신은 유용한 테스트를 작성하지 못했습니다.

목표는 관심있는 로직에 대한 테스트 적용 범위의 품질을 향상시키고 조기 피드백을 얻는 것입니다. 코드 리팩토링에 영향을 미치지 않으면 서

부작용을 격리하고 Nock와 같은 도구의 사용을 애플리케이션의 경계로 제한하십시오.

그것은 당신에게 변화를 주거나 깨뜨리지 않을만큼 충분한 자신감을 줄 것입니다.

싸움에 참여하고 부작용을 밀고 나서…

읽어 주셔서 감사합니다. 의견이 있으시면 Twitter, Facebook 또는 Github에서 문의하십시오.

이 게시물에 대한 통찰력있는 피드백을 주신 Eduardo Slompo와 Guilherme J. Tramontina에게 감사드립니다.