金融科技公司Nubank为什么杀死自己的端到端测试套件 ?


作为一家金融科技公司,质量对我们来说至关重要。我们需要客户用他们的钱信任我们。我们的端到端测试套件补充了我们的测试策略,以确保我们的系统具有非常高的质量和完整性。
过去,在 Nubank,我们使用端到端测试套件在临时环境中跨微服务架构边界查找问题。这意味着服务之间的交互通常由实际数据库、消息传递系统、HTTP 请求等支持。 
事实证明,这种做法有很多缺点。在我在这里工作的早期,我对工程痛点进行了评估。与许多不同的人和团队交谈时,与这种类型的测试的斗争成为一个共同的主题。
 
端到端测试套件的问题
大多数公司仍然认为端到端集成测试是捕获错误的最佳方式。但由于我们在评估期间发现的这些痛点,他们的价值交付也逐渐放缓:

  1. 等待。工程师不得不等待越来越多的时间才能从这个长期运行的套件中获得反馈;
  2. 缺乏信心。脆弱的测试意味着我们必须经常重新运行套件,以查看是否真的有问题或只是假阴性;
  3. 昂贵的维护。临时环境中的手动更改损坏了测试数据固定装置,并且保持环境“干净”是一项挑战;
  4. 失败并不指向明显的问题。测试失败很难调试,特别是由于我们依赖异步通信,这使得很难将失败的原因(未发布到队列的消息)与其影响(未在另一个系统中进行的更改)联系起来;
  5. 较慢的价值交付。端到端套件中的提交排队导致部署频率降低;
  6. 效率不高。在此阶段捕获的错误很少。一项实验表明,每 1000 次运行,我们有 42 次失败,只有 1 个错误;
  7. 没有效果。在生产中仍然发现错误。

在向 CTO 和工程领导展示我的评估结果时,我介绍了情况: 
“如果这些趋势继续下去,我们将在持续集成和部署管道中花费越来越多的时间,最终发现自己陷入困境。人们将提交越来越多的更改,这些更改将需要更长的时间来部署,同时仍然面临生产中出现错误的风险”。
 
新希望:合约测试
这种诊断对于 Nubank 来说并不是什么新鲜事或特定的东西。在我之前的经历中,我在许多财富 500 强公司中看到了同样的情况,它们在端到端测试自动化方面遇到了困难。但在 Nubank,我们决心改变这一点。我们的一位高级工程师Rafael Ferreira 计算了一些数字并应用了排队理论。他确定到 2021 年 Nubank 的端到端测试套件将需要……无限的运行时间! 
因此,我们决定探索消费者驱动合同 (CDC) 测试作为一种选择。
契约测试CDC允许我们通过输入和输出满足的期望来描述我们的服务之间的交互。例如,计费服务需要客户的名字和姓氏来生成帐单。因此,我们可以根据契约来描述计费和客户服务之间的交互:客户服务暴露端点 GET /customers/{id} 并期望收到一个有效的 UUID。 
 
总结一下:
  • 当事情仍然很简单并且仅限于一个团队时,端到端测试在项目开始时很有帮助。然而,随着项目和团队的成长,它们开始成为瓶颈,因为它们需要团队和基础设施工作之间的协调以保持它们的可靠运行。 
  • 另一方面,合同测试需要较少的协调和基础设施。这意味着团队可以相互独立发展。这在微服务架构中特别有用,因为集成点的数量往往呈指数增长。

 
为什么我们选择构建自己的框架
这些合约的声明和验证方式取决于相关的合约测试框架。然而,一个共同的特点是输入和输出被收集和验证,而无需针对在类似生产环境中运行的实际实例执行黑盒测试。
 这种概念的实现可能会有所不同: 
  1. 可以通过一种生成测试来验证声明性模式;或者
  2. 针对模拟服务器测试客户端应用程序(我们示例中的计费服务)发出的调用,该服务器使用实际服务器(客户服务)返回的相同数据进行响应。 

第二种方法是Pact实现的方法。我们开始了它,因为它是一个用于编写合约测试的非常整合的框架。然而,在我们的第一个实验中,有两个方面引起了我们的注意:
  • JVM 实现中对消息测试的支持还不成熟:我们微服务之间的大部分关键交互都是通过 Kafka 消息发生的(我们喜欢异步流中的突变,而 HTTP 调用主要保留用于只读操作)。因此,对异步交互的可靠支持对我们来说是一个关键因素;
  • JVM 版本对Clojure缺乏令人满意的支持,Clojure是我们用于绝大多数微服务的编程语言。

我们决定创建Sachem,我们自己的合同测试框架,以弃用作为实践的分阶段的端到端测试。关于这个项目的一件有趣的事情是,我们意识到我们的微服务中已经有了合约。Clojure 有这个库Schema,它允许您丰富地描述数据结构。