프로바이더 테스트 작성
GitLab v19.1이 튜토리얼은 프로바이더 테스트를 처음부터 작성하는 과정을 안내합니다. 프로바이더 테스트는 매우 간단합니다. 컨트랙트 테스트 디렉터리 구조에 대한 자세한 내용은 테스트 스위트 폴더 구조를 참조하세요. service_provider 블록은 프로바이더 테스트가 정의되는 곳입니다.
이 튜토리얼은 프로바이더 테스트를 처음부터 작성하는 과정을 안내합니다. 이 튜토리얼은 컨슈머 테스트 튜토리얼의 후속편입니다. 시작하기 위해, 프로바이더 테스트는 pact-ruby를 사용하여 작성됩니다. 이 튜토리얼에서는 discussions.spec.js가 생성한 컨트랙트를 처리하는 프로바이더 테스트를 작성합니다. Pact는 컨슈머 주도 테스트 도구이므로, 이 튜토리얼은 작업할 컨트랙트를 이미 생성한 기존 컨슈머 테스트가 있다고 가정합니다.
골격 생성#
프로바이더 테스트는 매우 간단합니다. 목표는 테스트 데이터를 설정하고 해당 컨트랙트와 연결하는 것입니다. 먼저 spec/contracts/provider/pact_helpers/project/merge_request 아래에 get_discussions_helper.rb라는 파일을 생성하세요. 파일 이름을 helpers라고 지정한 것은 이 튜토리얼 끝에 설정하는 Rake 태스크에서 Pact가 파일을 호출하는 방식과 일치시키기 위해서입니다.
컨트랙트 테스트 디렉터리 구조에 대한 자세한 내용은 테스트 스위트 폴더 구조를 참조하세요.
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
컨슈머와 프로바이더 이름 지정 방법에 대한 자세한 내용은 명명 규칙을 참조하세요.
테스트 앱 구성#
프로바이더 테스트가 컨트랙트를 검증하려면 실제 요청을 수행하고 컨트랙트와 비교할 응답을 반환하는 테스트 앱에 연결해야 합니다. 이를 위해 테스트에서 사용할 app을 spec/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 태스크를 추가하세요. 해당 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을 파싱하고 전달된 requester에 따라 컨트랙트가 로컬에 저장되는지 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의 프로바이더 테스트는 이것으로 통과되어야 합니다.