有关契约使用的概念性问题

时间:2019-04-05 12:51:23

标签: java spring-boot pact pact-jvm greybox

我是“开拓”整个公司使用契约的团队的一员。在此过程中,我们遇到了许多问题,这些问题主要是由于误解了CDC测试中协议的使用。随着时间的流逝,其中许多问题可能会得到解决,但是仍然有一些主要问题,我找不到任何好的解决方案或示例。由于我认为回答这些问题是非常基本的,因此我认为尝试直接与您联系可能会对我们有所帮助。

  1. 问题::在实施提供程序测试时,应在应用程序的哪个“层”上实施测试?
    背景:当我们第一次向应用程序添加带有契约的CDC测试时,我们通过启动一个应用程序上下文(包括内存数据库)来进行功能测试,并在该数据库中设置数据。这导致难以维护的测试,此外,我们实际上是在进行功能测试,而事实并非如此。在对要如何多次执行测试的方法进行了彻底思考之后,我们最终仅测试了我们的边界,该边界包括其余接口以及(最好是)输入和输出验证。
  2. 问题:使用多个提供商状态背后的想法是什么?
    背景:Pact支持对一个交互使用多个提供程序状态。我们尝试了此功能,但许多开发人员并不认为在多个提供程序状态中有很大的优势。因此,我们的许多带有契约的cdc测试都描述了冗长而复杂的提供者状态。因此,我认为我们不了解有关此功能的基本概念。
  3. 问题:参数化提供者状态背后的想法是什么?
    背景:与以前基本相同的背景。我们尝试了此功能,但许多开发人员决定不使用它。由于拒绝使用此功能是因为无法完全理解该功能,因此我想知道该功能的用途。
  4. 问题:我们应该如何处理有关版本控制策略的协定?
    背景:目前,官方pact documentation中记录了使用语义版本控制处理应用程序之间的合同。我们使用SNAPSHOT版本控制,并且当前无法选择更改版本控制策略。此外,我们公司中还有多个其他团队,它们具有不同的版本控制策略。基本上不可能就一种策略达成共识。当我们谈论在整个公司中使用带契约的cdc时,这意味着什么?那会导致什么问题?正确标记合同(主,功能,开发,生产...)可以解决有关版本控制的任何问题吗?

3 个答案:

答案 0 :(得分:3)

  1. 您的提供商测试不应受Pact的影响。您应该继续编写单元测试和功能集成测试(所谓集成,是指确保服务中不同组件正常工作的测试)。
    Pact添加的内容是您CI配置的新步骤。在构建期间,您应该使用pact-provider-verifier来获取使用者创建的协定,然后根据提供者进行重播,并将实际响应与该协定中定义的预期响应进行比较。这样,您可以验证提供商是否可以满足消费者定义的预期交互。
  2. 我认为多个提供者状态背后的主要思想是订单和代码的可重用性。想象一下,您的消费者定义了与以下提供者状态的2种交互:

    • “存在ID为123的用户,并且有一条帖子”
    • “存在ID为123的用户,该用户属于管理组”


    这两个状态在它们之间共享一些逻辑,因此像这样设置提供程序状态会很快变得混乱。相反,将以下状态映射到分别设置每个状态的代码会更好:

    • “存在ID为123的用户”
    • “用户123有一个帖子”
    • “用户123属于管理员组”
  3. 如果回头看上面的示例,您会发现提供商现在与ID 123的用户非常耦合。如果消费者决定将其更改为ID 456,这将破坏提供商的设置实施。因此,想法是将“ 123”作为参数传递,而不是在状态描述字符串中传递。该协定将如下所示:

"providerStates": [{
  "name": "The user exists",
  "params": {"id" : 123}
}]
  1. 文档中描述的语义版本控制只是一种建议,也是一种最佳实践。我认为您选择的任何版本控制策略都行得通,甚至在服务/团队之间也不必保持一致。

答案 1 :(得分:2)

除了西蒙回答的是什么

  1. 如果您看测试金字塔,契约测试就位于单元测试和集成测试之间。但是,如果您可以将它们向下推入单元空间,它们将变得更易于维护。在编写联系方式测试时,我会专注于“联系方式”以确保它没有做更多的事情。
  2. 西蒙回答2和3很好。多个提供程序状态的真正原因是有人要它。我不使用它们,一个对我来说总是足够的。
  3. 再次如西蒙回答。我们引入参数是因为我们注意到消费者测试和提供者测试之间存在测试数据耦合。使用者正在使用的数据必须与提供者状态下的数据匹配,以便提供者生成的响应与使用者有关。这使脆性测试。在参数之前,必须将数据编码到描述中以破坏耦合。我编写了很多提供程序状态方法,这些方法在描述中运行正则表达式以提取数据。
  4. 唯一的要求是为使用者和提供者提供唯一的版本。他们不必使用相同的方案。每个发布的契约以及发布的提供者验证结果都必须是可识别的。版本也必须是顺序的,因此代理可以从较新的版本中分辨出较旧的版本。语义版本控制非常适合。时间戳也可以在这里工作。不太容易阅读。

答案 2 :(得分:2)

首先,我想说很高兴您主动为整个公司试用Pact:)

我们正在努力改善Pact的沟通方式,因为我们了解到解决或传递给其他开发人员不是一个简单的问题。您对改善文档/网站的任何建议将不胜感激。

现在,进入以下问题:

  

实施提供程序测试时,应在应用程序的哪个“层”上实施测试?

协议实际上试图替换/增强集成测试,或者某些人会在提供者方面考虑功能测试。但是,对于某些公司/团队而言,这种命名方式的翻译效果并不理想,因为有些公司/团队会使用“功能”测试作为通过浏览器进行的端到端测试。

从本质上讲,Pact可以替换您过去以特定方式攻击提供商的任何测试,然后验证输出,因为这实际上是Pact所做的;这样做的主要优点是,它不是基于提供者的开发人员认为这些输入/输出应具有的功能,而是着重于消费者实际使用它的方式。

  

问题:使用多个提供者状态背后的想法是什么?

正如Simon所言,多个提供者状态只是一种促进数据重用和防止开发人员反复重做样板代码的方法。从本质上讲,这只是一种以可重复的方式设置数据需要的方式,而不是浪费时间为每个状态创建数据。话虽这么说,有时您的提供程序非常简单,以至于根本不需要此功能。

  

问题:参数化提供者状态背后的想法是什么?

参数是将某些可变数据注入状态(例如ID)的一种快速简便的方法,交互操作可能需要检查该数据是否完全相同,或者还可以将其与多个状态一起使用来创建ID。具体情况,例如“创建ID为X的用户”,然后“禁用ID为X的用户”。

  

问题:关于版本控制策略,我们应该如何处理协定?

协议提到了处理版本控制的最佳实践,即语义版本控制;始终是了解用户是否更新代码/依赖项,修复,添加或破坏性内容的好方法。

但是,Pact并未丝毫强制执行此操作,这实际上取决于您要如何执行。最后,在经纪人方面,合同只是用字符串“标记”。话虽如此,您可能需要合并策略,因为这不仅影响提供商,而且影响消费者,因此需要更高程度的协作。

我希望这些回答您所有的问题。如您所见,Pact可以针对不同的用例和策略开放,因为我们了解并非每个人都以相同的方式工作,但同时,它更着重于用户以确保他们有效地协作并设置供所有人使用的标准,否则可能会变得凌乱。契约可以给您足够的绳索来垂吊自己。

干杯

M