提供者テストの記述

このチュートリアルでは、ゼロからプロバイダテストを書く方法を説明します。消費者テストのチュートリアルの続きです。はじめに、プロバイダテストは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 で定義されています。個々のテストを実行する個々の 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 はヘルパーモジュールで、pact_helper_location を解析し、渡されたrequester に応じて契約がローカルまたは Pact Broker のどこに保存されているかを決定する#contract_location メソッドを持っています。

同時に、test:merge_requests Rakeタスクに含まれるように、新しい:get_discussions 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 のプロバイダテストはパスするはずです。