【问题标题】:Conceptual questions regarding usage of pact关于使用契约的概念性问题
【发布时间】:2019-04-05 12:51:22
【问题描述】:

我是一个团队的一员,该团队正在为我们整个公司“开拓”使用协议。在这段旅程中,我们遇到了许多问题,这些问题主要是由于误解了 CDC-Testing 协议的使用。随着时间的推移,其中很多问题都可以解决,但仍有一些主要问题我无法找到任何好的解决方案或示例。由于我认为回答这些问题非常重要,因此我认为尝试直接与您联系可能会对我们有所帮助。

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

【问题讨论】:

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


    【解决方案1】:
    1. 您的提供程序测试不应受到 Pact 的影响。您应该继续编写单元测试和功能集成测试(集成是指确保服务中的不同组件一起正常工作的测试)。
      Pact 为您的 CI 构建增加了一个新步骤。在构建期间,您应该使用pact-provider-verifier,它获取消费者创建的协议,针对您的提供者重放它,并将实际响应与协议中定义的预期响应进行比较。这使您可以验证您的提供者是否可以满足消费者定义的预期交互。
    2. 我认为多个提供者状态背后的主要思想是顺序和代码的可重用性。想象一下,您的消费者定义了 2 个与以下提供者状态的交互:

      • “存在 ID 为 123 的用户,并且有一个帖子”
      • “存在ID为123的用户,属于admin组”


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

      • “存在 ID 为 123 的用户”
      • “用户 123 有一篇文章”
      • “用户123属于admin组”
    3. 1234563执行。所以想法是将“123”作为参数传递,而不是在状态描述字符串中传递。该协议将如下所示:
    "providerStates": [{
      "name": "The user exists",
      "params": {"id" : 123}
    }]
    
    1. 文档中描述的语义版本控制只是一个建议和最佳实践。我认为您选择的任何版本控制策略都会奏效,甚至不必在服务/团队之间保持一致。

    【讨论】:

      【解决方案2】:

      除了西蒙的回答:

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

      【讨论】:

        【解决方案3】:

        首先,我想说的是,您主动为整个公司试用 Pact 真是太好了 :)

        我们正在努力改进我们与 Pact 沟通的方式,因为我们知道要解决或将其传递给其他开发人员并不是一个简单的问题。您可以提出任何改进文档/网站的建议,我们将不胜感激。

        现在,进入问题:

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

        Pact 本质上试图替换/增强集成测试,或者某些人认为提供者方面的功能测试。但是,对于某些公司/团队来说,这种命名法并不能很好地翻译,因为有些公司/团队会使用“功能”测试作为通过浏览器进行端到端测试的意思。

        本质上,Pact 可以替换您过去以特定方式打击您的提供者的任何测试,然后验证输出,因为这本质上是 Pact 所做的;这样做的主要优点是它不是基于提供者的开发者认为这些输入/输出应该是什么,而是强调消费者如何实际使用它。

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

        正如 Simon 已经说过的,多个提供者状态只是促进数据重用和防止开发人员一遍又一遍地重做样板代码的一种方式。它本质上只是一种以可重复的方式设置数据应该是什么样子的方法,而不是浪费时间为每个状态创建数据。话虽如此,有时您的提供商很简单,根本不需要此功能。

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

        参数是向状态注入一些可变数据(如 ID)的一种快速简便的方法,交互可能需要准确检查 ID 是否完全相同,或者您也可以将其与多个状态一起使用来创建一个特定情况,例如“创建 id X 的用户”,然后“禁用 id X 的用户”。

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

        Pact 提到了处理版本控制的最佳实践,即语义版本控制;它一直是了解用户是否更新其代码/依赖项、是否是修复、添加或破坏的好方法。

        但是,Pact 丝毫没有强制执行此操作,这完全取决于您要如何执行此操作。最后,在经纪人方面,合同只是用字符串“标记”。话虽如此,您可能希望巩固您的策略,因为这不仅会影响提供者,还会影响消费者,因此需要更高程度的协作。

        我希望这些回答您的所有问题。正如您所看到的,Pact 对不同的用例和策略相当开放,因为我们知道并非每个人的工作方式都相同,但同时,它更加强调用户以确保他们有效地协作并设置所有人都可以使用的标准,否则它可能会变得混乱。可以这么说,契约给了你足够的绳子让你上吊。

        干杯,

        M

        【讨论】:

          猜你喜欢
          • 2011-02-28
          • 2019-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多