프로바이더 테스트 작성

이 자습서는 제로에서 프로바이더 테스트를 작성하는 방법을 안내합니다. 이는 컨슈머 테스트 자습서의 계속입니다. 먼저, 프로바이더 테스트는 pact-ruby를 사용하여 작성됩니다. 이 자습서에서는 discussions.spec.js에서 생성된 계약을 다루는 프로바이더 테스트를 작성합니다. Pact는 컨슈머 중심의 테스트 도구이므로, 이 자습서는 이미 우리가 작업할 계약을 생성한 기존 컨슈머 테스트가 있다고 가정합니다.

뼈대 생성

프로바이더 테스트는 매우 간단합니다. 목표는 테스트 데이터를 설정한 다음 해당 계약과 연결하는 것입니다. 먼저 spec/contracts/provider/pact_helpers/project/merge_request 폴더 아래에 get_discussions_helper.rb라는 파일을 생성합니다. 이러한 파일은 이 자습서의 마지막에 설정되는 Rake 작업에서 Pact에 의해 호출되는 방식과 일치하도록 helpers 라고 부릅니다.

계약 테스트 디렉토리가 구조화된 방법에 대한 자세한 내용은 테스트 스위트 폴더 구조를 참조하십시오.

service_provider 블록

service_provider 블록은 프로바이더 테스트가 정의되는 곳입니다. 이 블록에는 서비스 프로바이더에 대한 설명을 넣습니다. 이것은 컨슈머 테스트에서 파생된 계약에서 호출되는 방식과 정확히 동일하게 명명합니다.

require_relative '../../../spec_helper'

module Provider
  module DiscussionsHelper
    Pact.service_provider 'GET discussions' do

    end
  end
end

honours_pact_with 블록

honours_pact_with 블록은 이 프로바이더 테스트가 다루는 컨슈머를 설명합니다. service_provider 블록과 유사하게, 이것은 컨슈머 테스트에서 파생된 계약에서 사용된 이름과 정확히 동일하게 명명합니다.

require_relative '../../../spec_helper'

module Provider
  module DiscussionsHelper
    Pact.service_provider 'GET discussions' do
      honours_pact_with 'MergeRequests#show' do

      end
    end
  end
end

소비자와 프로바이더의 이름을 짓는 방법에 대한 자세한 내용은 네이밍 컨벤션을 참조하십시오.

테스트 앱 구성

프로바이더 테스트가 계약을 확인하려면 실제 요청을 하는 테스트 앱에 연결해야 합니다. 이를 위해 테스트에서 사용하는 appspec/contracts/provider/environments/test.rb에 정의된 Environment::Test.app로 구성합니다.

require_relative '../../../spec_helper'

module Provider
  module DiscussionsHelper
    Pact.service_provider 'GET discussions' do
      app { Environment::Test.app }

      honours_pact_with 'MergeRequests#show' do

      end
    end
  end
end

확인할 계약 정의

이제 테스트 앱이 구성되었으므로, 이 프로바이더 테스트가 확인하는 계약을 정의하기만 하면 됩니다. 이를 위해 pact_uri를 설정합니다.

require_relative '../../../spec_helper'

module Provider
  module DiscussionsHelper
    Pact.service_provider 'GET discussions' do
      app { Environment::Test.app }

      honours_pact_with 'MergeRequests#show' do
        pact_uri '../contracts/project/merge_requests/show/mergerequests#show-merge_request_discussions_endpoint.json'
      end
    end
  end
end

Rake 작업 추가/업데이트

테스트가 생성되었으므로, 이 테스트를 실행하는 Rake 작업을 만들어야 합니다. Rake 작업은 개별 테스트를 실행하는 것뿐만 아니라 여러 테스트를 실행하는 것을 정의하는 lib/tasks/contracts/merge_requests.rake에 정의됩니다.

contracts:merge_requests 네임스페이스 아래에서 이 새로운 테스트를 실행하는 Rake 작업을 도입합니다. 여기에서 pact_uri를 호출하여 계약의 위치 및 해당 계약을 테스트하는 프로바이더 테스트를 정의합니다. 여기서 pact_uri에는 pact_helper라는 매개변수가 있습니다. 이것이 프로바이더 테스트가 _helper.rb로 호출되는 이유입니다.

Pact::VerificationTask.new(:get_discussions) do |pact|
  provider = File.expand_path('../../../spec/contracts/provider', __dir__)
  pact_helper_location = "pact_helpers/project/merge_requests/show/get_discussions_helper.rb"

  pact.uri(
    Provider::ContractSourceHelper.contract_location(:rake, pact_helper_location),
    pact_helper: "#{provider}/#{pact_helper_location}"
  )
end

Provider::ContractSourceHelper#contract_location 메서드를 가진 helper 모듈로, pact_helper_location을 구문 분석하고 requester에 따라 계약이 로컬에 저장되어 있는지 또는 Pact Broker에 있는지를 결정하는 도우미입니다.

동시에 새로운 :get_discussions Rake 작업을 test:merge_requests Rake 작업에 포함시켜야 합니다. 해당 Rake 작업에서 배열이 정의되어 있으며 (%w[get_diffs_batch get_diffs_metadata]),get_discussions을 그 목록에 추가해야 합니다.

테스트 데이터 생성

마지막 단계로, 서비스 제공자 테스트가 계약의 예상 응답을 반환하도록 하는 테스트 데이터를 생성합니다. 왜 테스트 데이터를 마지막에 생성하는지 궁금할 수 있습니다. 실제로 이것은 선호에 따라 다릅니다. 이미 테스트가 구성되어 있으면 테스트를 쉽게 실행하여 필요한 모든 테스트 데이터가 생성되어 예상한 응답을 생성하는지 확인할 수 있습니다.

서비스 제공자 상태에 대해 더 알아볼 수 있습니다. 전역 서비스 제공자 상태를 설정할 수 있지만, 이 튜토리얼에서는 제공자 상태가 특정 “상태”를 가지도록 설정합니다.

테스트 데이터를 생성하려면 spec/contracts/provider/states/project/merge_requests 디렉토리 아래에 show_state.rb 파일을 생성합니다. 또한 get_discussions_helper.rb 파일에서 이 상태 파일을 가져와야 합니다.

spec/contracts/provider/spec_helper.rb에 기본 사용자

테스트 데이터를 생성하기 전에 spec_helper에 기본 사용자가 생성됩니다. 이 사용자는 테스트 실행에 사용되는 사용자입니다. 이 사용자는 실제로 RSpec 기반으로 구축된 Pact를 사용하여 구성됩니다. 이 단계를 통해 테스트 실행 전에 사용자를 구성할 수 있습니다.

RSpec.configure do |config|
  config.include Devise::Test::IntegrationHelpers
  config.include FactoryBot::Syntax::Methods

  config.before do
    user = create(:user, name: Provider::UsersHelper::CONTRACT_USER_NAME).tap do |user|
      user.current_sign_in_at = Time.current
    end

    sign_in user
  end
end

필요한 경우 사용자에 대한 추가 수정은 개별 제공자 상태 파일을 통해 수행할 수 있습니다.

provider_states_for 블록

상태 파일에서 이 제공자 상태가 어떤 소비자에 대한 것인지 정의해야 합니다. 이를 provider_states_for로 수행할 수 있습니다. 제공되는 name이 소비자에 정의된 이름과 일치하는지 확인하세요.

Pact.provider_states_for 'MergeRequests#show' do
end

provider_state 블록

provider_states_for 블록 안에서 이제 테스트 데이터가 어떤 상태인지 정의해야 합니다. 이러한 상태는 소비자 테스트에서도 정의됩니다. 이 경우에는 '병합 요청에 논의가 있는 경우' 상태가 있습니다.

Pact.provider_states_for "MergeRequests#show" do
  provider_state "a merge request with discussions exists" do

  end
end

set_up 블록

여기에서 테스트 데이터 생성 단계를 정의합니다. FactoryBot을 사용하여 데이터를 생성합니다. 테스트 데이터를 생성하는 동안 서비스 제공자 테스트를 계속 실행하여 테스트의 상태를 확인하고 데이터 설정에 빠뜨린 부분을 찾을 수 있습니다.

Pact.provider_states_for "MergeRequests#show" do
  provider_state "a merge request with discussions exists" do
    set_up do
      user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME)
      namespace = create(:namespace, name: 'gitlab-org')
      project = create(:project, name: 'gitlab-qa', namespace: namespace)

      project.add_maintainer(user)

      merge_request = create(:merge_request_with_diffs, id: 1, source_project: project, author: user)

      create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: user)
    end
  end
end

테스트 데이터 사용

이제 제공자 상태 파일이 생성되었으므로, 이 상태 파일을 서비스 제공자 테스트에 가져와야 합니다.

# frozen_string_literal: true

require_relative '../../../spec_helper'
require_relative '../../../states/project/merge_requests/show_state'

module Provider
  module DiscussionsHelper
    Pact.service_provider "GET discussions" do
      app { Environments::Test.app }

      honours_pact_with 'Merge Request#show' do
        pact_uri '../contracts/project/merge_requests/show/mergerequests#show-merge_request_discussions_endpoint.json'
      end
    end
  end
end

이로서 get_discussions_helper.rb에 대한 서비스 제공자 테스트는 통과해야 합니다.