프로바이더 테스트 작성하기

이 튜토리얼은 처음부터 프로바이더 테스트를 작성하는 방법을 안내합니다. 이는 소비자 테스트 튜토리얼의 연속입니다. 시작하기 위해, 프로바이더 테스트는 pact-ruby를 사용하여 작성됩니다. 이 튜토리얼에서는 discussions.spec.js에서 생성된 계약을 다루는 프로바이더 테스트를 작성합니다. Pact는 소비자 주도 테스트 도구이므로, 이 튜토리얼은 우리가 작업할 계약을 이미 생성한 기존 소비자 테스트가 있다고 가정합니다.

스켈레톤 만들기

프로바이더 테스트는 상당히 간단합니다. 목표는 테스트 데이터를 설정한 다음 이를 해당 계약과 연결하는 것입니다. 먼저 spec/contracts/provider/pact_helpers/project/merge_request 아래에 get_discussions_helper.rb라는 파일을 만드세요. 이 파일은 Pact가 Rake 작업에서 호출하는 방식을 맞추기 위해 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

소비자와 프로바이더의 명명 방법에 대한 더 많은 정보는 명명 규칙을 참조하세요.

테스트 앱 구성

프로바이더 테스트가 계약을 검증할 수 있으려면, 실제 요청을 수행하고 계약에 대해 검증할 응답을 반환하는 테스트 앱에 연결해야 합니다. 이를 위해 테스트가 사용하는 appEnvironment::Test.app으로 구성하세요. 이는 spec/contracts/provider/environments/test.rb에서 정의됩니다.

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에서 정의되어 있으며, 여기에는 개별 테스트를 실행하는 개별 Rake 작업뿐만 아니라 테스트 그룹을 실행하는 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 메서드를 포함한 헬퍼 모듈로, pact_helper_location을 파싱하여 계약이 로컬에 저장되었는지 또는 Pact Broker에 저장되었는지를 결정합니다.

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

테스트 데이터 생성

마지막 단계로, 제공자가 계약의 예상 응답을 반환할 수 있도록 하는 테스트 데이터를 생성합니다. 왜 마지막에 테스트 데이터를 생성하는지 궁금할 수 있습니다. 이는 실제로 개인의 취향 문제입니다. 테스트가 이미 구성된 상태에서, 필요한 모든 테스트 데이터가 생성되어 예상 응답을 생성하는 데 적합한지 확인하기 위해 쉽게 테스트를 실행할 수 있습니다.

제공자 상태에 대해 자세히 읽어볼 수 있습니다. 우리는 전역 제공자 상태를 설정할 수 있지만, 이 튜토리얼에서는 제공자 상태가 특정 state에 해당합니다.

테스트 데이터를 생성하기 위해 spec/contracts/provider/states/project/merge_requests 아래에 show_state.rb를 생성합니다. 이 상태 파일을 get_discussions_helper.rb 파일에도 가져오는 것을 잊지 마세요.

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

테스트 데이터를 생성하기 전에, spec_helper에서 기본 사용자가 생성되며, 이는 테스트 실행에 사용되는 사용자입니다. 이 사용자는 Pact가 실제로 RSpec 위에 구축되어 있기 때문에 RSpec.configure를 통해 구성됩니다. 이 단계에서는 모든 테스트 실행 전에 사용자를 구성할 수 있습니다.

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 블록 내에서, 테스트 데이터가 어떤 상태인지를 정의합니다. 이러한 상태는 소비자 테스트에서도 정의됩니다. 이 경우, 'a merge request with discussions exists' 상태가 있습니다.

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에 대한 프로바이더 테스트는 이제 이로써 통과해야 합니다.