프로바이더 테스트 작성

이 자습서는 프로바이더 테스트를 처음부터 작성하는 방법을 안내합니다. 이 consumer test tutorial의 연속입니다. 먼저, 프로바이더 테스트는 pact-ruby를 사용하여 작성됩니다. 이 자습서에서는 discussions.spec.js에서 생성된 계약을 다루는 프로바이더 테스트를 작성합니다. Pact는 소비자 중심 테스트 도구이므로, 이미 계약을 생성한 기존 소비자 테스트가 있다고 가정합니다.

뼈대 만들기

프로바이더 테스트는 매우 간단합니다. 목표는 테스트 데이터를 설정하고 해당 데이터를 해당 계약과 연결하는 것입니다. 먼저, spec/contracts/provider/pact_helpers/project/merge_request 폴더 아래 get_discussions_helper.rb라는 파일을 만듭니다. 이 파일들은 이 자습서의 끝에서 설정된 Rake 작업에서 Pact에 의해 호출되는 방식과 일치하기 위해 helpers로 불립니다.

계약 테스트 디렉터리의 구조에 대한 자세한 정보는 Test suite folder structure를 참조하십시오.

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

소비자 및 프로바이더의 이름을 지정하는 방법에 대해 더 많은 정보는Naming conventions를 참조하십시오.

테스트 앱 구성

계약을 확인하려면 프로바이더 테스트를 테스트 앱에 연결하여 실제 요청을 만들고 응답을 확인해야 합니다. 이를 위해 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_uripact_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을 구문 분석하고 requester에 따라 로컬이나 Pact Broker에 계약이 저장된 위치를 결정합니다.

동시에, :get_discussions Rake 작업을 test:merge_requests Rake 작업에 포함시켜야 합니다. 해당 Rake 작업에서는 배열(%w[get_diffs_batch get_diffs_metadata])이 정의되어 있는데, 여기에 get_discussions을 추가해야 합니다.

테스트 데이터 작성

마지막 단계로, 프로바이더 테스트가 예상 응답을 생성할 수 있는 테스트 데이터를 작성합니다. 왜 테스트 데이터를 마지막에 작성하는지 궁금할 수도 있습니다. 이는 실제로 선호에 달린 문제입니다. 이미 테스트가 구성되어 있으므로, 필요한 테스트 데이터를 생성하여 예상 응답을 생성하는지 확인할 수 있습니다.

provider states에 대해 더 읽어볼 수 있습니다. 우리는 전역 프로바이더 상태를 설정할 수 있지만, 이 자습서에서는 하나의 특정 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 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의 공급자 테스트가 통과해야 합니다.