InfoGrab DocsInfoGrab Docs

컨트랙트 테스팅

요약

컨트랙트 테스트는 컨슈머(consumer) 테스트와 프로바이더(provider) 테스트의 두 부분으로 구성됩니다. 컨슈머 테스트는 단위 테스트와 유사하며, 각 스펙은 요청과 예상되는 목(mock) 응답을 정의한 후 해당 정의를 기반으로 컨트랙트를 생성합니다.

컨트랙트 테스트는 컨슈머(consumer) 테스트와 프로바이더(provider) 테스트의 두 부분으로 구성됩니다. 컨슈머와 프로바이더 관계의 간단한 예시는 프론트엔드와 백엔드 사이의 관계입니다. 프론트엔드가 컨슈머이고 백엔드가 프로바이더입니다. 프론트엔드는 백엔드가 제공하는 API를 소비합니다. 이 테스트는 두 측이 합의된 컨트랙트를 따르도록 보장하며, 컨트랙트에서 벗어나는 경우 의미 있는 대화를 유도하여 브레이킹 체인지(breaking change)가 그냥 통과되지 않도록 합니다.

컨슈머 테스트는 단위 테스트와 유사하며, 각 스펙은 요청과 예상되는 목(mock) 응답을 정의한 후 해당 정의를 기반으로 컨트랙트를 생성합니다. 프로바이더 테스트는 통합 테스트와 유사합니다. 각 스펙은 컨트랙트에 정의된 요청을 실제 서비스에 실행하고, 컨트랙트와 응답을 비교하여 유효성을 검증합니다.

기존 컨트랙트 테스트는 다음 경로에서 확인할 수 있습니다:

컨트랙트 파일 자체는 현재 /spec/contracts/contracts에 저장되어 있습니다. 향후 AWS에 호스팅된 PactBroker 또는 이와 유사한 서비스를 사용할 계획입니다.

테스트 작성#

컨슈머 테스트 실행#

컨슈머 테스트를 실행하기 전에 spec/contracts/consumer로 이동하여 npm install을 실행하세요. 모든 컨슈머 테스트를 실행하려면 npm run jest:contract -- /specs를 실행하면 됩니다. 특정 스펙 파일만 실행하려면 /specs 대신 해당 스펙 파일명을 입력하면 됩니다. 컨슈머 테스트를 실행하면 프로바이더 테스트가 실제 API 동작을 검증하는 데 사용할 컨트랙트가 생성됩니다.

프로젝트 루트 디렉터리에서도 yarn jest:contract 명령어를 사용하여 테스트를 실행할 수 있습니다.

프로바이더 테스트 실행#

프로바이더 테스트를 실행하기 전에 GDK(GitLab Development Kit)가 완전히 설정되어 실행 중인지 확인하세요. 설정 방법은 GDK 리포지터리에 있는 설정 안내를 참조하세요. 프로바이더 테스트를 실행하려면 ./lib/tasks/contracts에 있는 Rake 태스크를 사용합니다. 프로바이더 테스트 관련 Rake 태스크 목록을 확인하려면 bundle exec rake -T contracts를 실행하세요. 예시:

$ bundle exec rake -T contracts
rake contracts:merge_requests:pact:verify:diffs_batch                                   # Verify provider against the consumer pacts for diffs_batch
rake contracts:merge_requests:pact:verify:diffs_metadata                                # Verify provider against the consumer pacts for diffs_metadata
rake contracts:merge_requests:pact:verify:discussions                                   # Verify provider against the consumer pacts for discussions
rake contracts:merge_requests:test:merge_requests[contract_merge_requests]              # Run all merge request contract tests

Pact Broker에서 컨트랙트 검증#

기본적으로 Rake 태스크는 로컬에 저장된 컨트랙트를 검증합니다. Pact Broker에 게시된 컨트랙트를 검증하려면 PACT_BROKER 환경 변수를 true로, QA_PACT_BROKER_HOST를 Pact Broker의 URL로 설정해야 합니다. 프로바이더 테스트의 파일 경로와 파일명이 Pact Broker에서 컨트랙트를 찾는 데 사용된다는 점을 유의하세요. 따라서 프로바이더 테스트 명명 규칙을 반드시 준수해야 합니다.

Pact Broker에 컨트랙트 게시#

컨슈머 테스트로 생성된 컨트랙트는 QA_PACT_BROKER_HOST 환경 변수를 설정하고 publish-contracts.sh 스크립트를 실행하여 호스팅된 Pact Broker에 게시할 수 있습니다.

테스트 스위트 폴더 구조 및 명명 규칙#

컨슈머 테스트와 프로바이더 테스트 스위트를 체계적이고 유지보수하기 쉽게 유지하려면 테스트가 잘 정리되어 있어야 하며, 컨슈머와 프로바이더의 이름이 일관성 있게 지정되어야 합니다. 따라서 다음 규칙을 준수하는 것이 중요합니다.

테스트 스위트 폴더 구조#

테스트 스위트에 잘 정리된 합리적인 폴더 구조를 갖추면 리뷰, 디버깅, 또는 테스트를 추가할 때 관련 파일을 더 쉽게 찾을 수 있습니다.

컨슈머 테스트#

컨슈머 테스트는 애플리케이션의 각 페이지에 따라 그룹화됩니다. 각 파일에는 해당 페이지에서 발견되는 다양한 유형의 요청이 포함됩니다. 이에 따라 컨슈머 테스트 파일은 Rails 표준에서 페이지를 참조하는 방식으로 명명됩니다. 예를 들어, 프로젝트 파이프라인 페이지는 Project::Pipelines#index 페이지이므로, 이에 해당하는 컨슈머 테스트는 consumer/specs/project/pipelines/index.spec.js에 위치합니다.

테스트로 생성된 컨트랙트의 출력 위치를 정의할 때는 동일한 파일 구조를 따릅니다. 이 예시에서는 contracts/project/pipelines/가 됩니다. consumer/resourcesconsumer/fixtures도 동일한 구조를 따릅니다.

폴더 이름은 Rails 명명 표준에서 사용하는 방식과 일치하도록 복수형으로 지정해야 합니다.

프로바이더 테스트#

프로바이더 테스트는 컨트롤러와 유사하게 그룹화됩니다. 각 테스트에는 API 엔드포인트에 대한 다양한 테스트가 포함됩니다. 예를 들어, 프로젝트의 파이프라인 목록을 가져오는 API 엔드포인트는 provider/pact_helpers/project/pipelines/get_list_project_pipelines_helper.rb에 위치합니다. 프로바이더 상태(state)는 컨슈머 테스트와 마찬가지로 애플리케이션의 각 페이지에 따라 그룹화됩니다.

명명 규칙#

컨슈머 테스트와 프로바이더 테스트를 작성할 때 컨슈머와 프로바이더의 이름을 지정해야 하는 부분이 있습니다. Pact에서는 이름 지정 방식에 제한을 두지 않으므로, 디버깅 시 어떤 컨슈머 테스트와 프로바이더 테스트가 관련되어 있는지 쉽게 파악할 수 있도록 명명 규칙을 정하는 것이 중요합니다. Pact는 컨슈머와 프로바이더 이름을 사용하여 #{consumer_name}-#{provider_name} 형식으로 로컬에 저장되는 컨트랙트 파일명을 생성합니다.

컨슈머 명명#

폴더 구조 섹션에서 언급했듯이, 컨슈머 테스트는 애플리케이션의 각 페이지에 따라 그룹화됩니다. 따라서 컨슈머 이름도 Rails 표준을 사용하여 동일한 명명 형식을 따라야 합니다. 예를 들어, Project::Pipelines#index에 대한 컨슈머 테스트는 project 폴더 아래에 있으며 컨슈머 이름은 Pipelines#index가 됩니다.

프로바이더 명명#

프로바이더는 컨슈머에 데이터를 제공하는 API 엔드포인트이므로, 해당하는 API 엔드포인트에 따라 이름을 지정합니다. HTTP 요청 메서드로 시작하고 나머지 이름은 가능한 한 구체적으로 작성하는 것이 중요합니다. 예를 들어, GET /groups/:id/projects 엔드포인트에 대한 테스트를 작성할 때 "GET projects endpoint"로 이름을 짓지 않도록 주의하세요. GET /projects라는 엔드포인트도 있으며 이 역시 GitLab 전체에서 사용자가 접근할 수 있는 프로젝트 목록을 가져오기 때문입니다.

적절한 이름을 선택하려면 API 문서를 참고하여 동일한 방식으로 이름을 지정하되, 이름은 문장 형식(sentence case)으로 유지하세요. GET /groups/:id/projectsGET list a group's projects로 명명하고 테스트 파일명은 get_list_a_groups_projects_helper.rb로 지정합니다. GET /projectsGET list all projects로 명명하고 테스트 파일명은 get_list_all_projects_helper.rb로 지정합니다.

테스트 대상 프로바이더가 문서화되지 않은 경우도 있습니다. 이 경우 HTTP 요청 메서드로 시작하고 프로바이더가 무엇인지 쉽게 알 수 있도록 가능한 한 구체적인 이름을 붙이는 방식으로 대체하세요.

규칙 요약#

테스트 폴더 구조 명명 규칙
컨슈머 테스트 Rails 참조 표준을 따릅니다. 예: Project::Pipelines#index는 consumer/specs/project/pipelines/index.spec.js Rails 명명 표준을 따릅니다. 예: Project::Pipelines#index는 project 폴더 내에서 Pipelines#index로 명명합니다.
프로바이더 테스트 Rails 컨트롤러처럼 그룹화됩니다. 예: GET list project pipelines API 엔드포인트는 provider/pact_helpers/project/pipelines/get_list_project_pipelines_helper.rb API 문서 명명 체계를 문장 형식으로 따릅니다. 예: GET /projects/:id/pipelines는 GET list project pipelines로 명명합니다.

컨트랙트 테스팅

GitLab v19.1
원문 보기
요약

컨트랙트 테스트는 컨슈머(consumer) 테스트와 프로바이더(provider) 테스트의 두 부분으로 구성됩니다. 컨슈머 테스트는 단위 테스트와 유사하며, 각 스펙은 요청과 예상되는 목(mock) 응답을 정의한 후 해당 정의를 기반으로 컨트랙트를 생성합니다.

컨트랙트 테스트는 컨슈머(consumer) 테스트와 프로바이더(provider) 테스트의 두 부분으로 구성됩니다. 컨슈머와 프로바이더 관계의 간단한 예시는 프론트엔드와 백엔드 사이의 관계입니다. 프론트엔드가 컨슈머이고 백엔드가 프로바이더입니다. 프론트엔드는 백엔드가 제공하는 API를 소비합니다. 이 테스트는 두 측이 합의된 컨트랙트를 따르도록 보장하며, 컨트랙트에서 벗어나는 경우 의미 있는 대화를 유도하여 브레이킹 체인지(breaking change)가 그냥 통과되지 않도록 합니다.

컨슈머 테스트는 단위 테스트와 유사하며, 각 스펙은 요청과 예상되는 목(mock) 응답을 정의한 후 해당 정의를 기반으로 컨트랙트를 생성합니다. 프로바이더 테스트는 통합 테스트와 유사합니다. 각 스펙은 컨트랙트에 정의된 요청을 실제 서비스에 실행하고, 컨트랙트와 응답을 비교하여 유효성을 검증합니다.

기존 컨트랙트 테스트는 다음 경로에서 확인할 수 있습니다:

컨트랙트 파일 자체는 현재 /spec/contracts/contracts에 저장되어 있습니다. 향후 AWS에 호스팅된 PactBroker 또는 이와 유사한 서비스를 사용할 계획입니다.

테스트 작성#

컨슈머 테스트 실행#

컨슈머 테스트를 실행하기 전에 spec/contracts/consumer로 이동하여 npm install을 실행하세요. 모든 컨슈머 테스트를 실행하려면 npm run jest:contract -- /specs를 실행하면 됩니다. 특정 스펙 파일만 실행하려면 /specs 대신 해당 스펙 파일명을 입력하면 됩니다. 컨슈머 테스트를 실행하면 프로바이더 테스트가 실제 API 동작을 검증하는 데 사용할 컨트랙트가 생성됩니다.

프로젝트 루트 디렉터리에서도 yarn jest:contract 명령어를 사용하여 테스트를 실행할 수 있습니다.

프로바이더 테스트 실행#

프로바이더 테스트를 실행하기 전에 GDK(GitLab Development Kit)가 완전히 설정되어 실행 중인지 확인하세요. 설정 방법은 GDK 리포지터리에 있는 설정 안내를 참조하세요. 프로바이더 테스트를 실행하려면 ./lib/tasks/contracts에 있는 Rake 태스크를 사용합니다. 프로바이더 테스트 관련 Rake 태스크 목록을 확인하려면 bundle exec rake -T contracts를 실행하세요. 예시:

$ bundle exec rake -T contracts
rake contracts:merge_requests:pact:verify:diffs_batch                                   # Verify provider against the consumer pacts for diffs_batch
rake contracts:merge_requests:pact:verify:diffs_metadata                                # Verify provider against the consumer pacts for diffs_metadata
rake contracts:merge_requests:pact:verify:discussions                                   # Verify provider against the consumer pacts for discussions
rake contracts:merge_requests:test:merge_requests[contract_merge_requests]              # Run all merge request contract tests

Pact Broker에서 컨트랙트 검증#

기본적으로 Rake 태스크는 로컬에 저장된 컨트랙트를 검증합니다. Pact Broker에 게시된 컨트랙트를 검증하려면 PACT_BROKER 환경 변수를 true로, QA_PACT_BROKER_HOST를 Pact Broker의 URL로 설정해야 합니다. 프로바이더 테스트의 파일 경로와 파일명이 Pact Broker에서 컨트랙트를 찾는 데 사용된다는 점을 유의하세요. 따라서 프로바이더 테스트 명명 규칙을 반드시 준수해야 합니다.

Pact Broker에 컨트랙트 게시#

컨슈머 테스트로 생성된 컨트랙트는 QA_PACT_BROKER_HOST 환경 변수를 설정하고 publish-contracts.sh 스크립트를 실행하여 호스팅된 Pact Broker에 게시할 수 있습니다.

테스트 스위트 폴더 구조 및 명명 규칙#

컨슈머 테스트와 프로바이더 테스트 스위트를 체계적이고 유지보수하기 쉽게 유지하려면 테스트가 잘 정리되어 있어야 하며, 컨슈머와 프로바이더의 이름이 일관성 있게 지정되어야 합니다. 따라서 다음 규칙을 준수하는 것이 중요합니다.

테스트 스위트 폴더 구조#

테스트 스위트에 잘 정리된 합리적인 폴더 구조를 갖추면 리뷰, 디버깅, 또는 테스트를 추가할 때 관련 파일을 더 쉽게 찾을 수 있습니다.

컨슈머 테스트#

컨슈머 테스트는 애플리케이션의 각 페이지에 따라 그룹화됩니다. 각 파일에는 해당 페이지에서 발견되는 다양한 유형의 요청이 포함됩니다. 이에 따라 컨슈머 테스트 파일은 Rails 표준에서 페이지를 참조하는 방식으로 명명됩니다. 예를 들어, 프로젝트 파이프라인 페이지는 Project::Pipelines#index 페이지이므로, 이에 해당하는 컨슈머 테스트는 consumer/specs/project/pipelines/index.spec.js에 위치합니다.

테스트로 생성된 컨트랙트의 출력 위치를 정의할 때는 동일한 파일 구조를 따릅니다. 이 예시에서는 contracts/project/pipelines/가 됩니다. consumer/resourcesconsumer/fixtures도 동일한 구조를 따릅니다.

폴더 이름은 Rails 명명 표준에서 사용하는 방식과 일치하도록 복수형으로 지정해야 합니다.

프로바이더 테스트#

프로바이더 테스트는 컨트롤러와 유사하게 그룹화됩니다. 각 테스트에는 API 엔드포인트에 대한 다양한 테스트가 포함됩니다. 예를 들어, 프로젝트의 파이프라인 목록을 가져오는 API 엔드포인트는 provider/pact_helpers/project/pipelines/get_list_project_pipelines_helper.rb에 위치합니다. 프로바이더 상태(state)는 컨슈머 테스트와 마찬가지로 애플리케이션의 각 페이지에 따라 그룹화됩니다.

명명 규칙#

컨슈머 테스트와 프로바이더 테스트를 작성할 때 컨슈머와 프로바이더의 이름을 지정해야 하는 부분이 있습니다. Pact에서는 이름 지정 방식에 제한을 두지 않으므로, 디버깅 시 어떤 컨슈머 테스트와 프로바이더 테스트가 관련되어 있는지 쉽게 파악할 수 있도록 명명 규칙을 정하는 것이 중요합니다. Pact는 컨슈머와 프로바이더 이름을 사용하여 #{consumer_name}-#{provider_name} 형식으로 로컬에 저장되는 컨트랙트 파일명을 생성합니다.

컨슈머 명명#

폴더 구조 섹션에서 언급했듯이, 컨슈머 테스트는 애플리케이션의 각 페이지에 따라 그룹화됩니다. 따라서 컨슈머 이름도 Rails 표준을 사용하여 동일한 명명 형식을 따라야 합니다. 예를 들어, Project::Pipelines#index에 대한 컨슈머 테스트는 project 폴더 아래에 있으며 컨슈머 이름은 Pipelines#index가 됩니다.

프로바이더 명명#

프로바이더는 컨슈머에 데이터를 제공하는 API 엔드포인트이므로, 해당하는 API 엔드포인트에 따라 이름을 지정합니다. HTTP 요청 메서드로 시작하고 나머지 이름은 가능한 한 구체적으로 작성하는 것이 중요합니다. 예를 들어, GET /groups/:id/projects 엔드포인트에 대한 테스트를 작성할 때 "GET projects endpoint"로 이름을 짓지 않도록 주의하세요. GET /projects라는 엔드포인트도 있으며 이 역시 GitLab 전체에서 사용자가 접근할 수 있는 프로젝트 목록을 가져오기 때문입니다.

적절한 이름을 선택하려면 API 문서를 참고하여 동일한 방식으로 이름을 지정하되, 이름은 문장 형식(sentence case)으로 유지하세요. GET /groups/:id/projectsGET list a group's projects로 명명하고 테스트 파일명은 get_list_a_groups_projects_helper.rb로 지정합니다. GET /projectsGET list all projects로 명명하고 테스트 파일명은 get_list_all_projects_helper.rb로 지정합니다.

테스트 대상 프로바이더가 문서화되지 않은 경우도 있습니다. 이 경우 HTTP 요청 메서드로 시작하고 프로바이더가 무엇인지 쉽게 알 수 있도록 가능한 한 구체적인 이름을 붙이는 방식으로 대체하세요.

규칙 요약#

테스트 폴더 구조 명명 규칙
컨슈머 테스트 Rails 참조 표준을 따릅니다. 예: Project::Pipelines#index는 consumer/specs/project/pipelines/index.spec.js Rails 명명 표준을 따릅니다. 예: Project::Pipelines#index는 project 폴더 내에서 Pipelines#index로 명명합니다.
프로바이더 테스트 Rails 컨트롤러처럼 그룹화됩니다. 예: GET list project pipelines API 엔드포인트는 provider/pact_helpers/project/pipelines/get_list_project_pipelines_helper.rb API 문서 명명 체계를 문장 형식으로 따릅니다. 예: GET /projects/:id/pipelines는 GET list project pipelines로 명명합니다.