在一个没有管道的容器中使用契约对CI进行合同测试?

时间:2017-04-14 00:14:28

标签: pact

我正在尝试向我的团队介绍合同测试,而Pact似乎是唯一可靠的工具。

复杂的是,文档建议将其与微服务一起使用,并作为CI管道的一部分。但我们不能对我们的基础设施做出如此大的改变,而是尝试修改Pact使用以满足我们的需求。

我想使用Pact通过REST API测试JavaScript(Karma + Mocha)前端和Rails(Rspec)后端之间的通信。一切都运行正常,除了我无法使它在CI(Circle CI)上可靠地工作。 我们没有CI管道,因为它是在Pact docs中建议的,而是我们想要一个接一个地在一个容器中运行Consumer和Provider测试。工件将只存储在容器中的临时文件夹中,然后删除。

问题:在没有管道的容器中,是否有任何已建立且可靠的方法在CI上运行Pact测试?或者Pact不是这项工作的最佳工具?

我写了一个ruby脚本来完成它,但它常常因超时而崩溃:

def test_pact
  # wait for pact server to start, identify it by pid in the STDOUT
  server_init_message = "WEBrick::HTTPServer#start: pid="
  server_error_message = "(Errno::EADDRINUSE)"
  read_stream, write_stream = IO.pipe
  proc = ChildProcess.build("bundle", "exec", "rake", "pact:server")
  proc.io.stdout = proc.io.stderr = write_stream
  proc.leader = true # makes sure to kill all child forks of this process when it dies
  begin
    proc.start
    output_line = read_stream.gets
    until output_line.include?(server_init_message)
      puts "Waiting for Pact server to boot: #{Time.now}"
      output_line = read_stream.gets
      puts "Server output: #{output_line}"
      raise "Server boot error" if output_line.include?(server_error_message)
    end
    puts "Pact Server is booted"
    # Run JS tests:
    Dir.chdir("js") do
      run_or_exit("./build-support/circle.js", 'contract-karma.conf.js')
    end
    proc.stop
    # Run Ruby tests:
    run_or_exit("bundle exec rake pact:verify")
  rescue ChildProcess::TimeoutError, RuntimeError
    proc.stop
  end
end

和Rake任务:

require 'pact/tasks'
task :default => 'pact:verify'

# rake pact:server
namespace :pact do
  desc 'Run Pact Mock Server'
  task server: :environment do
    puts 'starting Pact mock server'
    system 'pact-mock-service --host localhost --port 1234 --pact_dir spec/contracts --consumer "Some Service" --provider "Some Service Provider" --pact_specification_version 2'
  end
end

2 个答案:

答案 0 :(得分:2)

Pact与CircleCI和其他托管的CI /构建服务完全兼容。然而,对于单个构建存在契约,并不是真的有意义。

根据您当前的使用案例,我建议如下:

  1. 将消费者和提供商测试拆分为单独的Circle CI构建。
  2. 设置独立的Pact Broker来存储契约(例如,托管您自己的Pact Broker或在http://pact.dius.com.au/获得免费的契约。)
  3. 将您的使用者构建(JS项目)中的契约发布到您的Pact Broker。
  4. 在您的Provider构建中,确保对pacts满意,否则构建失败。您可以使用pact_broker-client gem来实现此目的。
  5. 在您的消费者之后直接运行您的Provider构建会在某种程度上降低Pact的好处,因为每个服务都应该是可以独立部署的。

答案 1 :(得分:1)

了解karma pact时的情况。