本文讨论了阻塞团队自动化测试的五个典型问题。团队可以使用 API 和服务仿真来解决这些问题。
在过去的 15 年中,我与不同的软件团队合作过,我注意到使用在线测试替身(如 API 和服务仿真)是一些已经了解了该技术团队的标准实践。他们通常是具有 TDD 和 BDD 经验的敏捷或极限编程(XP)团队。
其他团队从未使用过模拟(mock)或仿真(simulator),主要是因为他们从未听说过它们。本文面向的是开始测试自动化之旅的团队,并展示了如何使用仿真来解决一些日常问题。
什么是 API 或服务仿真?
使用仿真来替代真正的微服务、第三方服务、大型机或其他软件系统则称为 API 和软件仿真。你还可以找到类似这样的工具,如API模拟、服务虚拟化、在线测试替身、以及用于存根和模拟HTTP(S)和其他协议的工具等。
这些技术的名称并不那么重要。重要的是,它们能够独立地进行组件(被测系统,SUT)测试。
你可以仿真API、服务或两者都仿真。我选择在本文中强调这两个名字,是因为我和我的客户发现,不同的团队其所熟悉的名称存在差异,这取决于他们所在的大洲或国家。
我还注意到,例如,在使用 HTTP 的开发和测试人员中,“API”是一个流行的短语,而当你是与第三方服务提供商合作的公司中的开发或 QA 负责人时,“服务”可能更流行。
我们使用图 1 中所示的微服务架构示例。这是一个典型的情景,我们有一个网站,该网站的后端有多个连接到数据库、第三方系统和遗留大型机的微服务。
图 1:生产中的微服务架构示例
图 2 展示了具有多个仿真的开发和测试基础设施。
图 2:使用 API 和服务仿真的开发和测试基础设施
自动化测试覆盖率
正如 Martin Fowler 十多年前所观察到的那样,度量测试覆盖率对于发现未经测试的代码非常有用,但作为质量目标却很糟糕。
我一开始时就提到这一点,是因为我在本文的部分内容中使用了代码覆盖率作为度量指标。我想澄清一下我所说的“20%的代码自动化测试覆盖率”是什么意思。这意味着,“我们知道我们有 20%的代码被不同类型的自动化测试覆盖了,但 80%的代码没有被测试覆盖。”这并不意味着“代码覆盖率是评估我们交付成果质量的一个很好的指标。”有更好的指标来衡量软件交付过程的质量,如这四个关键指标。BDD方式也有助于提高测试质量。
尽管如此,了解测试覆盖代码是一个好的开始。测试未涵盖的代码可能存在问题,如未检测到的错误或行为中的意外更改等。特别是,自动化测试覆盖具有提供可重复的回归套件或测试(测试工具)的特性,以帮助确保系统的行为在不同发布之间保持一致。
使用仿真解决测试自动化问题
在产品的开发和测试过程中,开发人员和测试人员可能会遇到如下的几个常见问题:
API 或服务尚不可用。
后端或第三方系统中的缓慢或手工过程。
测试数据问题(需要设置测试数据;测试数据更改会破坏现有的自动化测试;需要刷新测试数据)。
为错误场景测试设置假设场景。
第三方 API 和服务限制。
这些问题可以通过使用仿真来解决。下面我将详细介绍其中每种情况。
图 3 强调了在测试自动化过程的后期遇到这些问题时,这些问题是如何变得更严重的。
图 3:使用 API 和服务仿真更快地创建自动化测试
问题 1:API 或服务尚不可用
如果你所依赖的 API 或服务不可用,你可以使用API仿真来并行化团队协作并更快地交付产品。
但好处并不止于此,因为 API 仿真还能帮助你实现测试自动化。
假设你正在使用图 1 所示的 Purchasing 微服务。在 TDD 之后,你希望为依赖于 Payments 微服务的新 API 的新功能编写测试。不幸的是,支付团队仍在开发新的 Payments 微服务 API。当你测试 Purchasing 微服务时,它们没有可连接的 API。如果 API 不可用,自动化测试将会失败,除非使用测试替身(Test Double),例如 AP 仿真。
使用 API 仿真,可以为新的、不存在的 API 设置编程测试数据响应,然后运行测试。图 4 展示了这一工作流程。你不必等待支付团队,就可以继续开发和测试你的 Purchasing 微服务。
图 4:自动化测试设置 API 仿真并测试微服务
案例研究:API 尚不可用
我在《使用API优先开发和API模拟来打破关键路径依赖》一文中描述了一个示例用例,即四个团队在一个新平台的不同微服务上并行工作,这使他们能够极大地缩短上市时间。
这些团队使用API仿真工具为不存在的 API 创建仿真。仿真允许他们运行自动和手工的探索测试,而无需等待其他团队完成他们的工作。
他们遵循了如下的工作流程:
团队首先协作设计OpenAPI格式的 API。
生产者和消费者团队可以在他们的微服务上并行工作。
消费者团队可以使用仿真来模拟后端生产者服务,这允许编写不依赖于真实后端微服务的自动化测试。它还允许进行不依赖后端微服务的探索性手工测试。
在开发阶段就交流关于 API 规范的反馈对于 API 的发展和考虑不可预见的变化来说是至关重要的。
一旦微服务准备就绪,他们就可以在没有仿真的情况下一起测试微服务,并将微服务发布到生产环境中。
问题 2:后端或第三方系统中的缓慢或手工过程
阻碍团队创建自动化测试的另一个典型问题是测试用例中的缓慢或手工过程。
当使用异步技术(如 IBM MQ、RabbitMQ、JMS、ActiveMQ 或 AMQP)与依赖系统通信时,这种情况最为典型。
例如,如图 5 所示,微服务将向请求队列发送请求消息,以供后端服务使用。后端数据处理可能需要数分钟或数小时才能将响应消息响应到响应队列。
图 5:与后端进行请求和响应消息通信
在这种情况下,你的自动化测试可能会等待几分钟或几小时才能收到来自后端的响应消息。等待几分钟或几小时意味着每个测试用例都将阻塞构建管道几分钟或几个小时。因此,你需要一种替代方法来测试你的微服务。仿真将取代缓慢的依赖,并在几毫秒(而不是几分钟或几小时)内做出响应,从而使你的测试能够继续运行。图 6 展示了后端组件仿真的流程。
图 6:在请求和响应消息通信中使用仿真
当后端系统中存在手工请求文档处理时,你也将需要使用类似的方法。例如,在人机回环(human-in-the-loop)场景中,完成用户旅程和测试用例需要人与后端或第三方系统交互。像这样的手工过程通常需要花费比自动化测试所能接受的时间更长的时间,通常是几分钟、几小时或几天。
案例研究:后端或第三方系统中的手工过程
作为我日常工作的一部分,为一家从事政府项目的软件公司提供咨询,该公司希望自动化他们的手工回归测试。他们面临的挑战是,几乎所有的用户旅程都涉及将 IBM MQ 消息发送到政府服务进行处理。即使是在政府测试环境中,处理也是手工完成的。这一手工过程需要花费 30 分钟至 2 天的时间。团队使用Traffic Parrot模拟 IBM MQ 政府系统(免责声明:我代表 Traffic Pararot)。以毫秒而不是数小时或数天为响应单位的仿真解除了负责自动化手工回归测试的人员的阻塞。
问题 3:测试数据问题
当你运行自动化测试时,你需要相关的依赖系统来支持你的测试场景。这包括设置 API 和服务响应以匹配你的测试用例所需的内容。
在后台设置测试数据可能会存在问题,因为它们可能不在你团队的控制范围内。依靠另一个团队为你设置测试数据意味着你可能最终会得到不正确或缺失的测试数据,因此无法继续进行或运行自动化测试。
另一个问题是,即使你有了测试数据,在构建管道中频繁运行自动化测试可能会耗尽所有数据(测试数据燃烧)。然后,你需要刷新测试数据,这可能需要花费比设置部分测试数据更长的时间,而且你再次被阻塞。
即使你拥有所需的所有测试数据,当你(或其他团队)对相同的服务运行自动或手工测试时,测试数据可能会发生变化(例如,帐户余额或用户购买的商品列表)。测试会由于测试数据问题而不是产品的实际问题而再次中断。
你希望你的自动化测试在代码出现问题时失败,而不是在管理的测试数据出现问题时失败。
我们上面讨论的问题的解决方案之一是再次使用仿真。你可以根据单个测试在仿真中设置其所需的服务和 API 响应,这些响应将仅与给定的测试相关。这允许你在不依赖于其他团队和相关系统的情况下单独测试微服务。如图 7 所示。
图 7:根据自动化测试设置仿真
案例研究:在第三方系统中设置测试数据
我的一个媒体客户正在与第三方系统集成,他们只能通过特定的接口手工配置第三方系统中的测试数据。在持续一周的时间里,测试数据几乎每天都会被自动化测试使用/烧掉。他们在 2 小时内使用了一种流行的工具创建了一个简单的 API 仿真,这意味着他们不再需要在第三方系统中刷新测试数据了。在接下来的三个月里,他们又花了 20 个小时向仿真中添加了更多的响应,这些响应涵盖了他们想要的所有愉快的场景。此外,他们可以将错误场景添加到了仿真中,这在真实的第三方测试环境中是不可能配置的,从而进一步提高了自动化测试的覆盖率。
案例研究:仿真整个硬件环境
同一个客户使用 HTTP REST API 将微服务与硬件平台集成。不幸的是,仅仅是为自动化测试建立一个包含所有硬件设备的测试环境来支持所有的测试用例,就需要花费 6 个多月的时间来采购和安装测试环境所需的硬件设备。该团队决定花费 2 个开发人员两周的时间来创建一个软件设备仿真。构建一个具有足够功能的仿真来满足他们的需求,从而使得他们在无需等待测试环境新设备的情况下即可创建测试。
问题 4:为错误场景测试设置假设场景
除了上面提到的测试数据问题之外,有时甚至无法在测试环境中的某些系统中设置假设情况或错误用例。因此,如果你希望在自动化测试中包含一个生产环境的缺陷,并且它依赖于无法在测试环境中复现的后端系统的特定配置时,那么你就无法创建自动化测试。
当涉及到多个上游系统时,情况就更加复杂了。例如,如果 Payments 微服务连接到一些第三方 API 和大型机系统,则可能需要这些系统的特定响应组合来重现生产系统中发现的缺陷。
仿真再次前来救援。由于仿真完全在你的控制之下,你可以使用它来代替所有第三方和大型机系统,并详细设置假设情况。
你在生产环境中还会遇到不同类型的错误,如:
HTTP 及其他协议的错误响应(如 503 服务不可用,401 未授权)
响应缓慢
超时
运球响应(Dribbling responses)
断开的连接
所选的 API 和系统仿真工具将允许你模拟这些类型的错误,并允许将你的黑盒测试覆盖率提高到 80%以上。
案例研究:在第三方系统中设置错误场景
我向其提供咨询的一位客户,他的第三方服务有 23 种预期的错误场景需要考虑,因为它们很可能在正常的产品使用过程中发生。尽管如此,第三方环境仍不允许轻松地配置这些错误情况。为了自动测试这些场景,客户使用了一个 API 仿真,它可以返回指定的错误响应,并允许在所有这 23 个错误情况下对其软件进行自动地黑盒测试。
问题 5:第三方 API 和服务限制
许多第三方 API 或服务在生产环境中使用是存在限制的。其中包括:
节流或速率限制——每分钟或每小时的最大请求数
突发阈值——数秒内每秒的最大请求数
最大并行连接数
借助仿真,你可以模拟第三方节流、速率限制或最大并行连接数,这允许你在黑色星期五(Black Friday)场景中测试整个被测试系统的限制。
一些公司选择限制对其测试和沙盒环境的访问,以避免为其所有客户支持过多的测试基础设施而产生成本。使用仿真,你可以绕过第三方测试环境中的速率限制,并在你这一侧根据需要运行尽可能多的自动化功能和性能测试。
与生产环境相比,后端系统的测试环境可能比较缓慢,从而使你无法在得到类似于生产环境中运行自动化性能测试的体验。你可以使用仿真在测试环境中模拟生产环境的响应时间。
案例研究:速率受限的第三方 API
我的一个客户正在与第三方 API 集成,其突发阈值为连续 5 秒内每秒 3 次。达到限制后,API 返回一个 429 错误,“请求太多”。他们想要一个自动化测试,在这个测试中,他们的软件可以限制请求,以满足允许的突发阈值。他们创建了一个模拟第三方行为的仿真,当在 5 秒内每秒连续命中 3 次以上时,返回 429 错误“请求太多”。他们在自动化测试中验证了生产代码可以在一分钟内限制大量请求的功能。
下一步
学习新事物固然好,但如果不使用它们,它们就不会产生回报!
如果你是 QA 的负责人,并且有一个 KPI 是希望从手工测试转向自动化测试,请与你的团队一起检查下是否有遇到上述的任何问题。
如果你是一名架构师、开发人员或自动化测试人员,遇到了上面列出的一个或多个问题,请与你的团队和管理层谈谈,看看你是否可以花一些时间来研究使用仿真解决你的问题。
维基百科对API仿真工具进行了有益的比较,在那里,你可以找到适合你需求的工具。
如果你有任何特定于项目的问题,请随时通过LinkedIn、Twitter或电子邮件 wojtek @trafficparrot.com 联系我。
作者简介:
Wojciech Bulaty 专门从事企业软件开发和测试架构。他为自己的写作带来了十多年的实践编码和领导经验。他现在是 Traffic Parrot 团队的一员,通过提供 API 仿真和服务虚拟化工具,帮助微服务团队加快交付、提高质量并缩短上市时间。你可以在 Twitter 上关注 Wojciech,也可以在 LinkedIn 上联系他。
原文链接:
https://www.infoq.com/articles/test-automation-solutions/
相关阅读:
评论