출처: 2022년, Full Stack Testing - A Practical Guide for Delivering High Quality Software by Gayathri Mohan, 3장 Automated Functional Testing
통합 테스팅의 일환인 소비자 중심 계약 테스트(consumer-driven contract testing)에 대한 개념과 PACT 도구를 사용한 계약 테스팅 구현 예를 제시한다.
소비자 중심 계약 테스트
Pact는 Java로 계약 테스트(contract tests)를 생성하는 데 널리 사용되는 도구이다. Python, JavaScript, Go, Scala 및 기타 다른 언어로 작성할 수도 있다. Pact는 특히 소비자 중심 계약 테스트(consumer-driven contract testing)에 사용된다. 소비자(consumer)는 다른 애플리케이션(예: 서비스 또는 메시지 큐)에서 정보를 수신하는 애플리케이션(예: 서비스 또는 웹 UI)이고, 정보를 제공하는 애플리케이션은 공급자(provider)이다. 예를 들어, 전자상거래 애플리케이션의 주문 서비스(Order service)는 PIM 서비스로부터 판매업체의 품목 세부정보를 수신하므로 주문 서비스는 소비자가 되고 PIM 서비스는 공급자가 된다. 주문 서비스 말고도 다른 많은 소비자가 PIM 서비스를 사용할 수 있다. 또한 소비자마다 PIM 서비스에서 필요한 정보가 다를 수 있다.
요구 사항이 소비자 중심이라는 점을 감안할 때 PIM 서비스는 새로운 소비자 또는 새로운 요구사항을 충족하기 위해 계약을 변경해야 하는 상황에 처하게 될 수 있으며, 이는 주문 서비스 및 다른 소비자 팀에 리스크를 초래할 수 있다. 나중에 통합 이슈를 피하려면 PIM 서비스의 계약(특히 관련 애트리뷰트)이 변하지 않았는지 지속적으로 확인하는 메커니즘이 필요하다. 테스터나 개발자가 서비스 테스트 또는 통합 테스트를 작성하여 이 리스크를 완화할 수 있지만 이러한 테스트는 두 애플리케이션의 종속성으로 인해 불안정하고 느릴 수 있을 뿐만 아니라 설정 및 유지 관리 비용도 많이 든다. 때로는 공급자와 소비자가 동시에 개발을 진행하고 있을 수 있고, 이는 엔드-투-엔드 통합 테스트(또는 서비스 테스트)를 작성할 수도 없음을 의미한다. 소비자 중심의 계약 테스트는 이러한 얽힘을 해결하는 데 핵심이 된다.
그림 3-10에서 볼 수 있듯이 소비자 중심 계약 테스트에서 각 소비자 팀은 공급자가 합의한 계약의 스터브(stub) 버전에 대한 테스트를 작성한다. 이 테스트는 전체 계약이 아닌 해당 소비자가 기대하는 애트리뷰트를 구체적으로 확인(어써션) 한다. 그런 다음 이 테스트가 공급자 팀에 전달되고, 모든 테스트를 실제 공급자 API에 대해 실행하여 예상대로 소비자의 니즈를 충족하는지 확인한다. 편차가 발견되면 공급자 팀은 최소한 해당 소비자에게 변경에 대해 경고할 수 있다.
이러한 유형의 계약 테스트는 엔드투엔드 통합 테스트를 다음과 같이 여러 부분으로 나눈다.
- 각 소비자는 자신의 기능적 동작을 검증하기 위해 공급자를 스터빙하여 미시적 및 거시적 수준 테스트를 작성한다.
- 또한 각 소비자는 공급자의 스터브에 대한 계약 테스트를 작성하고, 공급자는 이를 지속적으로 실행한다.
- 공급자는 자신의 기능적 동작을 검증하기 위해 미시적 및 거시적 수준의 테스트를 작성한다.
계약 테스트 범위가 더 작고 종속성을 제거하므로 이를 통해 엔드투엔드 통합 테스트를 작성할 때 발생하는 고통을 완화할 수 있다.
Pact로 구현한 계약 테스트 예
Pact를 사용하면 계약 테스트 프로세스를 완전히 자동화할 수 있다. 전자상거래 애플리케이션의 주문 및 PIM 서비스 예에서 주문 서비스가 품목 세부정보(사용 가능한 크기, SKU 및 색상)을 조회하기 위해 외부 PIM 서비스의 GET /items 엔드포인트와 통합된다고 가정해 보자. 두 팀의 Pact 워크플로우가 다음과 같다.
- 첫 번째 단계로 주문 서비스 팀은 모든 통합 테스트 케이스를 수집 및 분류한다. 예를 들어 /items 엔드포인트가 존재하는 품목의 세부 정보를 예상대로 반환하는 경우, 품목이 존재하지 않아서 빈 어레이를 반환하는 경우, 잘못된 요청에 대해 적절한 에러 코드(404, 500 등)를 반환하는 경우 등의 통합 테스트 케이스가 분류된다.
- 주문 서비스 팀은 Pact를 사용하여 이러한 테스트 케이스에 대한 스터브를 생성한다.
- 주문 서비스 팀은 이러한 스터브에 대해 Pact를 사용하여 소비자 계약 테스트를 작성한다(상태 코드, SKU, 사용 가능한 크기 및 색상과 같은 특정 애트리뷰트에 대해 어써션 체크를 함). 이러한 테스트를 실행하면 자동으로 pact 파일이 생성된다. 이 파일은 /items 엔드포인트에 대한 여러 요청(requests)과 그 응답(responses)에 담긴 예상 애트리뷰트에 대한 어써션을 캡처한다.
- Pact 파일은 Pact Broker(소비자 팀과 공급자 팀 모두가 설정하고 유지 관리해야 하는 오픈 소스 조항)를 통해 자동으로 PIM 팀에 전달된다. Pact 팀은 Pact Broker를 설정하고 유지 관리할 필요가 없는 Pactflow라는 유료 서비스도 제공한다. 더 간단하게는 폴더를 통해 파일을 공유할 수도 있다.
- PIM 서비스 측 팀은 Pact Broker로부터 Pact 파일을 수신하고 소비자 테스트 요구사항에 따라 다양한 상태의 테스트 데이터를 설정하기 위해 공급자 계약 테스트를 작성한다. 공급자 테스트가 실행되면 Pact는 실제 PIM 서비스에 대해 Pact 파일에 기술된 대로 적절한 요청을 하고 실제 응답을 확인한다.
- 공급자 테스트 결과는 Pact Broker를 통해 소비자에게 제공되며 개입 없이 전체 피드백 루프가 완료된다.
- 소비자와 공급자의 Pact 테스트가 모두 CI 파이프라인에 통합되어 팀이 지속적으로 피드백을 받을 수 있다.
예제 3-19는 pactMethod를 사용한 샘플 Pact 소비자 테스트를 보여준다. 먼저 pactMethod는 Pact 소비자 테스트에서 의도한 대로 /items 엔드포인트의 상태를 설정한다. 아래 코드에서 given() 메소드가 이 상태를 지정하며, 적절한 테스트 데이터 설정을 시작하기 위해 공급자 테스트에서 이것을 참조한다. 그런 다음 Pact 소비자 테스트는 pactMethod에 기술된 대로 /items 스터브를 띄우고 품목 세부정보 응답을 확인(assert문을 사용한 어써션 체킹)한다.
이 테스트가 pact 파일을 생성하고 폴더를 통해 공급자와 공유된다. 예제 3-20의 Pact 공급자 테스트는 이 pact 파일을 수신하고, @State 주석이 달린 메서드에 따라 테스트 데이터 설정을 하고, Pact 파일의 지시에 따라 실제 /items 엔드포인트에 도달하고, 실제 응답에 예제 3-19에 기술된 것과 동일한 품목 세부정보가 있는지 어써션(확인)한다.
Pact는 CI와 통합할 수 있는 HTML 보고서를 생성한다. Pact 테스트는 일반적으로 애플리케이션 코드와 긴밀하게 연결되어 있으며 이를 생성하고 디버깅하려면 사용 중인 애플리케이션 개발 프레임워크(예: Spring Boot)에 대한 지식이 필요할 수 있다.
아래 7분 길이의 영상은 코드 예를 보여주면서 Pact 계약 테스트 구현 과정을 설명한다.
'개발생명주기단계별 > 통합_통합 테스팅' 카테고리의 다른 글
책 발췌 – API 테스팅 by Gayathri Mohan (0) | 2024.06.10 |
---|---|
책 발췌 –인터페이스 테스팅 by Everett and McLeod (1) | 2024.02.12 |
책 요약 – SQL 테스팅 (0) | 2021.12.21 |
페이퍼요약 - 단 대 단 통합 테스팅 설계 by Tsai (0) | 2019.07.29 |