所以你听说过Pact并希望开始。本指南应该有助于您朝着正确的方向前进。
什么是Pact?
Pact系列测试框架(Pact-JVM,Pact Ruby,Pact .NET,Pact Go,Pact.js,Pact Swift等)为依赖系统之间的消费者驱动合同测试提供支持,其中集成基于HTTP(或消息)某些实现的队列)。它们对于μ服务特别有用,在这些服务中可能存在大量相互依赖的服务,并且集成测试很快变得不可行。
在我们深入了解Pact之前,您需要了解消费者驱动的合同。
什么是消费者驱动的合同?
消费者驱动的合同是一种模式或方法,其中相互依赖的服务之间的合同是从服务消费者的角度设计的。它的主要文章是消费者驱动的合同:服务进化模式,但它在技术方面有点过时(它谈论了很多关于XML和模式)。但是文章中表达的概念与我们今天构建的计算机系统有关。
我发现很多时候构建μ服务或内部API的团队都遵循与外部或公共API相同的思路。服务提供商或API团队会考虑其服务的任何消费者需要的所有内容(在此过程中做出许多假设),然后提供服务以及如何使用它的文档。他们建立它并希望消费者来。
当他们稍后需要更改它时,他们会进行更改,然后将其与所有消费者需要遵循的说明一起发布以使用更新的API。它们可能包含多个版本的服务,以保护消费者免受重大变化的影响。
我目睹了第一手开发和使用API的两个团队。 在构建消费者和提供者之后,他们花了很多天才在集成测试环境中进行交互,因为消费者团队认为API将基于发布JSON文档(它是从Web浏览器调用),而 提供程序团队实现了application / x-www-form-urlencoded POST API。
但具有讽刺意味的是,对于内部API和服务而言,要弄清楚服务的所有消费者是谁以及他们的要求是什么并不难。 大多数时候,他们都在同一个组织工作。
消费者驱动的合同扭转了这一切。 交互合同由服务的消费者开发。
这种方法的好处是,您知道您的服务的所有消费者是谁,您将知道何时进行重大更改,以便更容易进行更改,合同也是一种文档形式。 其次,您将确切地知道需要提供哪些功能,以便您可以实现消费者所需的正确服务,并遵循YAGNI原则。
交互的发展始于消费者方面,希望通过测试。 消费者团队定义交互合同并根据合同实现服务使用者。
然后将此合同提供给提供者团队(在某些情况下,它是同一个团队),并且实施提供者服务以履行合同。
开始时我需要做什么?
大多数信息可以在Github页面上找到,用于各种Pact实现。 Ruby Pact在wiki中有很多信息。
- Ruby Pact: https://github.com/realestate-com-au/pact
- JVM Pact: https://github.com/DiUS/pact-jvm
- .Net Pact: https://github.com/SEEK-Jobs/pact-net
- Pact Go: https://github.com/pact-foundation/pact-go
- Pact.js: https://github.com/pact-foundation/pact-js
- Pact Swift: https://github.com/DiUS/pact-consumer-swift
- Pact Python: https://github.com/pact-foundation/pact-python
特别是,要了解Pact的工作原理,请阅读:https://github.com/realestate-com-au/pact#how-does-it-work。
从消费者测试开始
这完全是关于消费者的,所以从那里开始。支持许多测试框架,因此根据您使用的测试工具,请阅读相关文档。
对于Ruby和RSpec,请阅读使用pacts简化微服务测试的示例。
对于基于JVM的测试框架(JUnit,Groovy等),请查看https://github.com/DiUS/pact-jvm#service-consumers。 JUnit似乎是最受欢迎的。有很多示例测试。
一旦运行了消费者测试,就应该生成pact文件。这些是消费者驱动合同意义上的合同。您可以通过多种方式发布这些文件。常见的方法是将它们提交到源存储库,将它们上载到文件服务器,将它们存储为CI构建中的工件或将它们上载到Pact Broker。
验证您的提供者
该方法的后半部分是验证您的提供商实际上是否符合消费者的期望。对于已实现消费者测试的每个消费者,您应该在某处发布pact文件。通常,您希望在其CI构建中验证您的提供商,以便您知道更改何时破坏了与消费者的交互,并且您还将知道您受影响的消费者。
给定一组已发布的pact文件,有两种主要方法可以验证您的提供程序是否遵守pact文件中封装的合同。
使用构建插件来验证协议
第一种方法是使用构建插件,该插件可以在pact文件中针对您的提供者执行请求。在某些情况下(如Ruby Rake任务),提供程序从测试工具(Rack Test for ruby)中启动,重放请求,然后将响应与pact文件的预期响应进行比较。在其他情况下(如Maven和Gradle插件),实际的提供程序需要运行,构建插件会向正在运行的提供程序发出实际请求。
有关为Ruby提供程序使用Ruby Rake任务的示例,请阅读使用pacts简化微服务测试的“提供程序”部分。
JVM构建插件(Maven,Gradle,Leiningen和SBT)的自述文件包含有关如何使用这些工具的更多信息。在大多数情况下,您需要能够事先启动您的提供程序并在之后停止它,并且有办法提供协议所需的测试数据。有关更多信息,请参阅Pact-JVM自述文件的“服务提供程序”部分。
Pact具有状态更改机制,用于在验证测试运行期间控制提供程序的状态。本质上,这是一个可以在每个请求之前调用的钩子,其中描述了提供者为了能够成功处理请求而需要的预期状态。例如“用户Andy应该存在”或“订单表应该为空”。 Ruby实现允许定义设置和拆除块,而JVM构建插件允许定义状态更改URL,该URL将在实际请求发出之前接收具有状态描述的POST请求。
使用测试框架来验证契约
使用某些构建插件的最大缺点是,您需要让您的提供程序运行,并且您需要能够设置测试数据。这涉及预先加载所有契约所需的夹具数据,或者使用状态更改机制来动态更改提供者的状态。这两种方法都需要相当多的编排,尤其是在CI环境中。
由于社区贡献,Pact JUnit提供程序运行程序可供使用基于JVM的提供程序的人员使用。它允许您仅处理提供者处理请求的部分提供者代码,并且您可以使用JUnit设置和拆除机制以及状态注释标记来设置协议所需的数据。您也可以使用标准的模拟框架来存根依赖关系,尽管我会添加一个警告,以确保您不会影响您的模拟和存根的行为。自述文件包含更多信息。
原文:https://dius.com.au/2016/02/03/microservices-pact/
讨论:加入知识星球【首席架构师圈】
最新内容
- 13 hours 23 minutes ago
- 15 hours ago
- 15 hours 55 minutes ago
- 3 days 6 hours ago
- 3 days 14 hours ago
- 3 days 14 hours ago
- 3 days 15 hours ago
- 3 days 15 hours ago
- 1 week 1 day ago
- 1 week 1 day ago