谷歌的测试工程师是如何工作,帮助开发工程师提升生产效率的

乔梁 | 2021-02-20

现在,越来越多的软件系统采用了「微服务架构」。尽管这种架构对于多人参与的大系统,为多个功能特性的并行开发与无停机部署提供了便利,但对整个系统的测试与运维提出了新的挑战。尤其是如何进行自动化功能测试。而这个问题早已有前人探路啦。

下面是谷歌某团队的测试工程师在 2016年 遇到的大规模服务自动化功能测试问题(复杂的遗留系统,臃肿且不稳定的自动化测试,以及超长的扫行时间),以及他们的解决方案。

翻新遗留系统需要新工具

几年前,我加入了一个工程团队,致力于用新的实现替换遗留系统。因为构建替换系统需要几年时间,所以我们必须保持遗留系统的正常运行,甚至添加功能,同时构建替换系统,这样才不会对外部用户造成影响。

遗留的系统非常复杂和脆弱,以至于工程师们花了大部分时间对 bug 和不可靠的测试用例进行分类和修复,几乎没有时间实现新功能。重写的目标是从遗留系统中学习,并构建更易于维护和扩展的东西。作为团队的测试工程师,我的工作是研究:什么导致了高昂的维护成本,以及如何改进。

我发现主要的原因有两个:

  • 紧耦合和抽象不充分使得单元测试非常困难。所以,工程师写了很多端到端的测试用例充当对这些代码的功能测试。
  • 非常大且脆弱不稳定的大型测试​。用于端到端测试的基础设施平法无法为这些被测服务创建和注入 fake 或 mock。因此,测试用例执行前必须找大量资源把这些外部依赖服务都运行起来。​这使得我们写的这些测试都成了大型测试。我们目前(2016年)的测试执行平台无法可靠地执行这些测试用例。

探索解决方案

起初,我探索是否可以将大型测试分成多个较小的测试,这些测试用例只测试特定的功能,并减少对外部服务的依赖。事实证明,这是不可能的,因为遗留代码的架构不合理。要让这种方法起作用,需要对整个系统及其依赖项进行重构,而这不仅仅是我自己所在的团队负责的部分。

在第二种方法中,我还将重点放在大型测试上,并尝试对那些在测试某个功能时,不需要的服务进行 mock 。这也被证明是非常困难的,因为依赖关系经常变化,而且在一个包含 200 多个服务的图中很难跟踪单个依赖关系。最终,这种方法只是将所需的工作从维护测试代码转移到维护测试依赖项和 mock 。

我的第三种也是最后一种方法,如下图所示,使小型测试更加强大。在我们面临的典型端到端测试中,客户端对几个服务进行了RPC调用,而这些服务又对其他服务进行了 RPC 调用。客户端和所有后端服务上的可传递闭包一起形成了一个超大的图(而不是树!)依赖项,所有这些都必须启动并运行才能进行端到端测试。新模型改变了我们测试客户端和服务集成的方式。我们不会以某种方式触发 RPC 调用的输入上运行客户端,而是为代码编写单元测试,对 RPC stub 进行方法调用。而 stub 本身可以使用Java语言中的 Mockito 这种通用模拟框架模拟。

对于每个这样的测试,第二个测试将验证用于驱动模拟的数据对实际服务是否“有意义”。这也可以通过单元测试来完成,在单元测试中,重放客户端使用RPC mock 用来调用服务的 RPC 处理程序方法的相同数据。

这种集成测试模式适用于任何RPC调用,因此可以像测试前端客户端调用一样测试后端服务器对另一个后端进行的 RPC 调用。当我们始终如一地应用此方法时,我们将受益于仍然测试正确集成行为的较小测试,并确保我们正在测试的行为是“真实的”。

为了得到这个解决方案,我不得不构建、评估和丢弃几个原型。虽然为这种方法构建概念验证花了一天的时间,但我和另一位工程师花了一年的时间才实现了开发人员可以使用的完整工具。

采纳

当工程师们看到新框架从他们的测试中删除了大量样板代码时,他们很快就接受了新的解决方案。为了进一步推动它的采用,我和工程团队组织了为期数天的活动,我们的重点是迁移测试用例。

花了几个月的时间将所有现有的单元测试迁移到新框架,弥补覆盖范围的差距,并创建验证 mock 的新测试。当我们转换了大约80%的测试以后,我们就开始比较新测试和现有端到端测试的效果。

效果非常好:

  • 新测试用例在发现缺陷方面与端到端测试一样有效。
  • 新端到端测试时间约为 3 分钟,而不是 30 分钟。
  • client 测试没有不稳定的。验证测试通常比端到端测试更可靠。

此外,新写的测试都是单元测试,因此可以在 IDE 中运行它们,并逐步调试它们。这样,我们可以很少运行端到端测试,只在检测交互服务的配置时使用,而不再把它们作为功能测试使用。

构建和改进测试基础设施,从而帮助工程师提高工作效率是测试工程师在谷歌做的众多事情之一。

做这个项目,从需求收集一直到成品,让我有机会设计和实现几个原型,推动一个解决方案的全面实现,带领工程团队采用新的框架,并将来自工程师的反馈和实际测量集成到工具的持续改进中。

本文来自于谷歌的测试博客,原文作者: Jochen Wuttke

原文链接:What Test Engineers do at Google: Building Test Infrastructure

原文发表时间: Nov 18, 2016