验证契约

关于本话题请先参考验证契约一节的介绍。

使用rake pact:verify

使用pact:verify任务是最常见的验证契约的方式。这也是配置你的服务提供者应遵守的契约的默认集之处。

在Rakefile中引入'pact/tasks'就可以使用了。

  1. # In Rakefile
  2. require 'pact/tasks'
  3. # Remember to add it to your default Rake task
  4. task :default => 'pact:verify'

pact:verify任务用于验证的契约是在提供者端代码库中的 pact_helper.rb 文件里进行配置的。该文件必须命名为 pact_helper.rb ,而其存储位置可以有一定程度的灵活性。推荐的存储目录是 spec/service_consumers/pact_helper.rb下。

为了保证每次使用的是消费者发布的最新版本的契约,推荐你要么使用Pact Broker,要么在消费者端成功构建之后将契约发布至你的CI系统中作为artefacts(产物)。

注意:Pact使用了Rack::Test,并假定你的服务提供者是一个Rack应用。如果你的提供者不是Rack应用,参见如下的选项说明。

  1. # In specs/service_consumers/pact_helper.rb
  2. require 'pact/provider/rspec'
  3. # Require the provider states files for each service consumer
  4. require 'service_consumers/provider_states_for_my_service_consumer'
  5. Pact.service_provider "My Service Provider" do
  6. # Optional app configuration. Pact loads the app from config.ru by default
  7. # (it is recommended to let Pact use the config.ru if possible, so testing
  8. # conditions are closest to runtime conditions)
  9. app { MyApp.new }
  10. honours_pact_with 'My Service Consumer' do
  11. # This example points to a local file, however, on a real project with a continuous
  12. # integration box, you would publish your pacts as artifacts,
  13. # and point the pact_uri to the pact published by the last successful build.
  14. pact_uri '../path-to-your-consumer-project/specs/pacts/my_consumer-my_provider.json'
  15. end
  16. # This block is repeated for every pact that this provider should be verified against.
  17. honours_pact_with 'Some other Service Consumer' do
  18. ...
  19. end
  20. end

使用基本的授权

从需要一些基本的授权的URL上验证某个契约时,只需添加用户名和密码选项:

  1. pact_uri 'http://...', {username: '...', password: '...'}

使用rake pact:verify:at从任意的URL来验证契约

你可以使用pact:verify:at任务对任意的本地或远程URL上的契约进行验证。

这在同时开发服务消费者和提供者,希望验证消费者代码库中生成的最新契约时十分有用。这里和pact:verify使用的pact_helper文件是相同的。

  1. $ rake pact:verify:at[../path-to-your-consumer-project/specs/pacts/my_consumer-my_provider.json]
  2. $ rake pact:verify:at[http://build-box/MyConsumerBuild/latestSuccessful/artifacts/my_consumer-my_provider.json]

如果需要基本的授权,请设置环境变量PACT_BROKER_USERNAMEPACT_BROKER_PASSWORD,或者使用基本授权URL格式,如http://username:password@pactbroker.yourdomain/...

验证存储在Amazon S3上的契约

Pact::Retreaty工具提供了一套极轻量级的机制,可以将pact契约推送到S3并从S3上拉取。

使用定制的pact:verify任务

如果希望定制一个快捷任务,能够验证任意URL的契约,又不想作为普通的pact:verify任务所验证契约的一部分时,(例如,当你并行开发消费者和提供者,并且希望得到比CI运行更短的反馈周期时)可以将下列内容添加到Rakefile中。pact.uri可以是一个本地文件系统路径或者一个远程URL。

  1. # In Rakefile or /tasks/pact.rake
  2. # This creates a rake task that can be executed by running
  3. # $ rake pact:verify:dev
  4. Pact::VerificationTask.new(:dev) do | task |
  5. task.uri '../path-to-your-consumer-project/specs/pacts/my_consumer-my_provider.json'
  6. end

如果需要基本的授权,请设置环境变量PACT_BROKER_USERNAMEPACT_BROKER_PASSWORD,或者使用基本授权URL格式,如http://username:password@pactbroker.yourdomain/...

每次只验证一个交互

在某些阶段,当你在逐步实现每个特性时,会希望具有每次只运行一个测试的能力。在运行失败的pact:verify输出结果的底部你可以看到能够用于独立重复运行每个失败测试的命令,它们看起来类似这样:

  1. $ rake pact:verify PACT_DESCRIPTION="a request for something" PACT_PROVIDER_STATE="something exists"

为非Rack应用验证契约

Ruby应用

如果你的应用是非Rack的Ruby应用,你也许能找到一个Rack适配器。如果找到了,那么将Pact.service_provider代码块里的app指向你的适配器的某个实例。否则的话,使用pact-provider-proxy gem吧。

配置RSpec

Pact使用动态创建出的RSpec用例来验证契约。如果你想修改底层RSpec执行过程的行为,你可以这样做:

  1. 在pact_helper中使用普通的RSpec.configure代码来配置RSpec。
  2. 或者在自定义的rake校验任务中设置task.rspec_opts,这与在普通的RSpec rake任务中进行声明起的效果一样。

不过深入一步讲,尝试使用提供者状态中的set_up/tear_down代码块吧,因为我们有可能将来会换掉RSpec中的自定义校验代码。

Pact Helper的位置

pact_helper的搜索路径如下:

  1. [
  2. "spec/**/*service*consumer*/pact_helper.rb",
  3. "spec/**/*consumer*/pact_helper.rb",
  4. "spec/**/pact_helper.rb",
  5. "**/pact_helper.rb"]