首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

微服务测试—六份案例研究和技术组合(第三部分)

本文要点

  • 测试微服务时,要考虑的一个重要因素是如何管理关联的依赖项。有很多种技术可以用来解耦依赖项,但是它们都有一些权衡,开发/QA团队必须意识到这一点。
  • 架构师、开发人员和QA团队必须共同努力,以理解和指定测试目标、上下文和当前的约束条件。
  • 制订一套全面的测试方法通常需要实施多种测试策略。必须仔细选择这些策略,以避免重复工作或增加测试套件的偶发复杂性。
  • 契约测试是验证服务之间交互的一种有价值的方法。可以将契约测试与精心挑选,数量有限的端到端测试相结合,以验证完整的业务流程。
  • Mock和服务虚拟化有助于在测试过程中解耦组件。应当精心确保这些测试替身处于正确状态,并与当前关联实现的最新版本保持同步。

这是《微服务测试》系列的第三篇文章。另请参见《微服务测试的 12 项实用技术(第一部分)》和《微服务测试的 12 项实用技术(第二部分)》。

我们Traffic Parrot最近与六家公司展开了合作,这些公司是众多行业领域的代表,并且在应用微服务方面有着成熟的经历。这些公司应用了我们在本系列第一部分中描述,并在第二部分中评估的一系列测试技术的组合,这些技术使你可以在测试微服务时管理从属组件。在第三部分中,我们将展示对应的案例研究,介绍这六家公司是怎样应用这些技术的。

首先我们介绍三份案例研究,这些案例中公司将测试技术的组合用作整体解决方案。后三份案例研究中,企业使用单一技术来解决特定问题。

技术组合:美国保险业初创公司

架构

Greenfield微服务取代了最近构建的单体架构。

技术栈

Go、Python、NodeJS、gRPC、Protocol Buffers、Docker和Kubernetes。

任务优先级

快速交付;将在首次生产发布后重构发布流程。

使用的测试技术

  • 技术#1——使用另一个微服务的测试实例测试你的微服务(端到端测试)
  • 技术#6——Mocks(进程内)
  • 技术#9——服务虚拟化(通过本地/远程)
  • 技术#11 —测试容器

契约管理

  • 团队使用API​​ mocks在彼此之间传达契约的语法和语义。
  • API mocks定义了自动测试的契约快照,以确保它们与最新的协议规范保持同步。

要点

  • 使用了gRPC协议API mocks来允许团队并行工作。
  • 使用自动化测试来确保API mocks不会过时。

这家初创公司有两个团队,当时他们在开发一组共三个新的微服务,必须在两个月内交付。这些微服务正在替换已弃用的一个单体架构的一部分内容。团队决定使用单元测试来测试Go微服务的内部组件,这些单元测试使用了进程内mocks,基于GoMock框架实现。他们使用组件级集成测试来测试与数据库的交互,该测试使用测试容器数据库来避免依赖数据库的共享实例。

为了管理团队之间的契约并允许团队并行工作,他们决定使用API​​生产者创建并与API消费者共享的API mocks。他们使用API​​ mocking工具创建了gRPC API服务mocks。

他们还在预生产环境中使用了一些手动端到端测试,以确保在没有足够的自动化测试的情况下,微服务也能协同工作。他们将在第一个期限之后填补自动化测试中的空白。

由于这是一个必须按时投入生产的绿地项目(新开发的项目),因此公司决定不对微服务API进行版本控制。相反,每次发布时他们将所有内容一起发布到生产环境(通常称为快照版本)。他们考虑到了服务的停机时间,以及与之关联的,面向客户的组件出现的小幅度功能退化,这些问题已事先通知客户。在发布第一个产品之后,他们开始对API进行语义版本化。这使他们能够更好地管理API更改,以实现向后兼容性并为客户提升正常运行时间。

他们在早期就遇到了另一个有趣的问题,那就是API mocks每天都会过时,因为API确实每天都在变化。这些更改通常不会向后兼容,因为开发人员正在重构协议文件以反映正在快速进化的领域模型,当时他们尚未明确定义这一模型。这种状况是绿地项目普遍所有的特征,其中项目团队使用迭代方法为客户交付价值。为了按时完成任务,公司决定同时向mock和真实的微服务发出请求来测试API mocks。他们将两者的响应与该公司专属的自定义格式所定义的"预期请求/响应对"的契约定义进行了比较。这样,与契约文件中定义的预期行为的最新定义比较后,API mocks和真实服务就可以被证明是最新状态了。

技术组合:西班牙电子商务公司

架构

从拥有十年历史的单体式服务器转向微服务。

技术栈

Java、HTTP REST、gRPC、protocols、JMS、IBM MQ、Docker和OpenShift。

任务优先级

采用API优先方法,以允许并行工作和解耦团队。在公司的3,000名开发人员中大规模采用微服务。

使用的测试技术

  • 技术#1——使用另一个微服务的测试实例测试你的微服务(端到端测试)
  • 技术#6——Mocks(进程内)
  • 技术#9——服务虚拟化(通过本地/远程)
  • 技术#11——测试容器

契约管理

  • 团队使用API​​ mocks在彼此之间传达契约的语法和语义。
  • 行为驱动开发(BDD)API测试,还可以验证API mock交互。
  • 这些API设计为始终向后兼容。

要点

  • 允许团队使用API​​ mocks实现的API优先方法来并行工作。
  • 开发人员根据OpenAPI和协议规范创建了mocks。

这家公司决定从单体架构迁移到更自治的团队组合和微服务上。在转型过程中,他们决定采用推荐的良好实践,而不是将特定的技术和解决方案强加给团队。

团队架构师负责收集开发人员要使用的技术、指南和工具。他们还负责创建一种架构,通过复用成熟的技术、工具和组件来最大程度地减少浪费。

开发人员编写了JUnitTestNG集成测试,并使用API​​ mocking工具mock了从属组件。他们还编写了Cucumber/GherkinBDDAPI验收测试来捕获业务需求(他们称其为“契约测试”),使用了微服务的Docker映像和称为Traffic Parrot的API mocking工具的Docker映像。BDD测试通过验证API mocks上的交互来验证微服务API和其与从属组件的交互。这样,BDD测试通过断言和验证来验证微服务API请求和响应,以及它与从属组件的所有通信。

该公司使用JMeter来创建性能测试。JMeter测试可以测试单个微服务,并使用真实依赖项(例如微服务和旧的单体组件)的API mocks替换从属组件。他们使用的一种技术是在API mocks上配置响应时间,并观察增加的延迟对所调用服务的影响。

所有的单元、验收和性能测试都在Bamboo持续交付管道中进行。

这家公司创建API mocks的方式很有趣。他们使用了两种方式。

如果开发人员想要消费的API已经存在,他们会记录请求和响应从而创建API mocks。开发人员首先在他们的计算机上创建一个新测试。然后,他们运行测试并记录测试内容从而创建API mocks。他们将测试和mocks提交给Git中的微服务项目。在QA管道(在每次提交时启动以检查产品质量的管道)中,他们启动了一个Docker容器,该容器运行API mocking工具并从微服务项目中加载mock定义。

如果微服务要消费的API尚不存在,则开发人员将根据HTTP REST API的OpenAPI规范创建API mocks,或根据gRPC API的协议文件创建API mocks

每当开发人员在测试套件中需要Cassandra数据库时,他们就会运行Cassandra数据库测试容器。这样做的好处是不必依赖数据库的中心化副本。他们使用自定义的Cassandra配置构建了自己的Docker映像。

他们还开发并运行自动化的端到端烟雾测试。这是测试微服务之间契约的技术之一,它能确保微服务组可以很好地协同工作。端到端测试套件的存在是有道理的,因为它不仅测试了在BDD测试中测试的契约生产者方,而且还测试了消费者方,因此提供了更多的可信度。架构师会监视端到端测试的数量。他们将端到端测试套件的复杂性保持在不会拖累发布流程或日常开发活动的水平。

技术组合:英国媒体公司

架构

在生产环境中已经有超过100种微服务,这些微服务运行在具备手动配置硬件的环境中。

技术栈

Java、HTTP REST、Docker和Kubernetes。

任务优先级

迁移至云(内部Kubernetes集群)。从运营团队管理的硬件迁移到Kubernetes集群上,后者由自治功能团队管理,从而降低基础架构成本并缩短面市时间。通过引入零宕机时间版本,将正常运行时间从99.5%提高到99.95%。

使用的测试技术

  • 技术#1——使用另一个微服务的测试实例测试你的微服务(在早期使用其他微服务进行手动探索性测试)
  • 技术#3——测试具有第三方依赖项的微服务(第三方的英国媒体基础设施测试API)
  • 技术#5——测试具有非软件(硬件)依赖项(网络硬件)的微服务
  • 技术#6——Mocks(进程内)
  • 技术#9——服务虚拟化(通过第三方服务和其他微服务的本地/远程API mocks)
  • 技术#11——测试容器(Oracle数据库测试容器、API mocks测试容器和从属微服务测试容器)

契约管理

  • 消费者驱动的契约以及集群中其他微服务的契约测试。
  • 第三方API每契约的窄集成测试。
  • 无回归端到端测试。
  • BDD API测试还可以验证API mocks交互。
  • 这些API向后和向前兼容(版本兼容性n±1)。

要点

  • 使用了消费者驱动的契约和消费者驱动的契约测试、BDD API测试以及API版本管理取代端到端测试。

这家公司现有一个包含100多个微服务的技术栈,主要使用自动化BDD端到端测试,但是它们的维护成本很高,因为开发人员需要花费大量时间来编写和调试测试套件。由于被测系统的复杂性导致测试不够稳定,所以开发人员经常会感到沮丧,从而导致许多不确定的故障点。这些测试还使他们无法做到按需发布新功能,因为这些测试需要花费几个小时才能运行完毕。他们意识到,这套复杂的测试套件花费的时间太久了,并且放弃它的成本也太高了。有关端到端测试问题的更多详细信息,请参阅Steve Smith撰写的"被认为有害的端到端测试"。

吸取了这些教训后,该公司决定不在其正在研究的新产品上实施端到端测试。这一产品将在新的内部Kubernetes集群上运行,并尽量减少端到端测试的使用,而应用新的契约管理技术。

为了针对新的微服务之间的契约以及整个产品行为来提升信心,他们使用的主要方法是以消费者驱动的方式设计契约。公司选择使用Pact-JVM来测试消费者驱动的契约。公司中的大多数团队是首次接触消费者驱动的契约,但他们很快就掌握了这种方法。

他们用来改善微服务的另一项技术是在每个功能团队中配备一名人工测试员。这名测试员将针对每个新用户故事进行手动探索性测试。测试时,这名测试员将在自己的计算机上使用Docker测试容器运行微服务,有时还会与其他微服务一起运行。

开发人员决定基于清洁架构的理念来实现某些微服务,这需要使用进程内mocking,这个案例中他们使用的是Mockito

作为Docker测试容器运行的API mocks被广泛用于mocking第三方的网络硬件和栈中的其他微服务。

当在TeamCity构建内部运行时,BDD验收测试使用WireMock进行API mocking。手动测试人员使用具有Web用户界面的API mocking工具进行探索性测试。这种方法简化了设置测试场景和测试微服务的工作。

解决特定问题:美国铁路公司

问题:

迁移到为自治团队提供的新CI/CD管道基础架构,需要一种服务虚拟化工具,该工具可以在管道内部运行,而不必使用共享环境。

解决问题的技术:

技术#11——测试容器(将API mocks作为Docker测试容器运行)

要点:

使用按需API-mock Docker测试容器来避免依赖共享的服务虚拟化基础架构。

这家公司决定从单体架构过渡到微服务架构上。在转型过程中,他们推动的一项主要变革是新的CI /CD管道基础设施。

负责设计管道架构的架构师希望使用在共享环境中部署的服务虚拟化。这样做的原因是这家公司已经有了适当的解决方案。虚拟服务已在团队之间共享,并且CI/CD会构建在现有的单体架构中。

经过仔细考虑,架构师意识到在新的微服务世界中,使用由众多管道、开发人员和测试人员共享的服务虚拟化环境效果会适得其反。公司转向微服务的原因之一就是让功能团队彼此独立地工作。依靠由中心化的团队管理的共享服务虚拟化环境并不会帮助他们实现这一目标。此外,任何共享环境都是一个单故障点,他们希望避免这种情况。

架构师决定,他们将使用API​​ mocks而不是共享的服务虚拟化环境,这些mocks将作为构建作业的一部分来部署。他设计了一种完全分布式的部署方法,其中API mocks会按需部署。一个Jenkins构建将在测试套件之前启动API-mock Docker测试容器并在OpenShift中运行。构建完成后,这些Docker容器将被拆除。

解决特定问题:以色列电子商务创业公司

问题:

将自动化API和第三方集成测试引入之前没有开发人员接触过它们的环境。

解决该问题的技术:

技术#9——服务虚拟化(使用第三方API虚拟服务的在线/远程服务,前者由使用现成服务虚拟化工具创建的数据库支持)

要点:

使用第三方API服务虚拟化工具创建由数据库支持的虚拟服务,以加快刚开始接触自动集成测试的开发人员的上手速度。

这家初创公司正在向市场推出新产品。开发人员正在添加新功能,但没做过自动API或第三方集成测试。他们必须快速发布新功能,因此没有多大空间来更改现有的开发流程。

QA自动化负责人在Jest中开发了API和集成测试框架。他使用了以前在许多项目中使用过的现成的商业服务虚拟化工具,从而创建了替代第三方API的虚拟服务。

该工具部署在了共享环境中,因为他相信这能让他对新测试方法的应用拥有更多控制权。每个单独的虚拟服务都由一个包含HTTP请求-响应映射数据的数据库表支持。他决定允许通过数据库设置虚拟服务,因为开发人员已经习惯在数据库中设置测试数据。他选择了开发人员比较熟悉的数据库MongoDB。

这是向这家创业公司的开发人员介绍各种类型的自动化API和集成测试的第一步。这位负责人认为,开发人员可以轻松掌握数据库驱动的虚拟服务。每人几个小时的入门时间就足以让开发人员开始编写他们的第一个自动集成测试。

解决特定问题:美国商品经销商

问题:

将亚马逊简单队列服务(Simple Queue Service,SQS)队列引入技术栈时,必须验证是否已将正确的消息发送到正确的队列,从而导致了手动测试问题。它还影响了自动化测试工作的成果。

解决问题的技术:

技术#8——服务虚拟化(通过亚马逊SQS模拟器本地/远程进行)

要点:

使用亚马逊SQS模拟器可以在测试时无需访问实际的SQS实例。

公司将亚马逊AWS组件引入他们的架构。不幸的是,组织中的开发和测试团队没有协作机制,因此测试团队要手动工作,而来自开发团队的帮助却很少。这意味着测试团队无法使用可帮助他们测试产品的工具。他们总是落后于开发团队,赶不上进度,还要在周末加班。最重要的是,他们被要求引入自动化测试,以逐渐开始摆脱手动回归测试。

其中一项技术挑战是使用亚马逊SQS队列手动并自动进行集成测试。为此,他们使用了带有用户界面的亚马逊SQS模拟器,这使他们可以模拟有状态的SQS队列,从而继续进行手动测试。他们使用模拟器的用户界面来检查队列中的消息,以手动验证请求消息。在它的帮助下,他们还开始使用SQS模拟器的API引入与SQS集成的自动化测试。

下一步

这里描述的案例研究只是这些组织中发生的事件的一个缩影。我们主要研究团队在测试时如何管理从属组件,并特别选择了这六份案例研究,因为它们代表了截然不同的方法。它们展示了团队如何根据环境和团队与任务相关的熟练程度来使用不同的技术。

我们很想听到读者的反馈和故事分享。在第一和第二部分中提到的技术中,你们见过有哪些实践案例呢?我们也非常希望听到你对第三部分中介绍的这些案例的评价,说说你们是否赞成他们的测试方法和技术选择。

请在文章下方发表评论,或通过LinkedIn或Twitter与我们联系。

如果你有任何关于特定项目的问题或疑问,请与作者联系:CEO Wojciech Bulaty,邮箱:wojtek@trafficparrot.com或@WojciechBulaty;技术主管Liam Williams,邮箱:liam@trafficparrot.com或@theangrydev_。

作者介绍:

Wojciech Bulaty是敏捷软件开发和测试架构专家。他将自己十余年的一线编程和领导经验用在了敏捷、自动化、XP、TDD、BDD、结对编程和简洁编码领域的文章写作中。他最近的成果是Traffic Parrot,其中他通过提供API mocking和服务虚拟化工具来帮助使用微服务的团队加速交付、提高质量并缩短产品面市时间。

Liam Williams是一位自动化专家,致力于通过高质量的软件解决方案来改进容易出错的手动流程。他是开源贡献者,并且是许多小型库的作者。最近他加入了Traffic Parrot的团队,进而将注意力转向了在转型现代微服务架构时改善测试体验的问题。

本文是《微服务测试》系列文章的第三篇。另请参见《微服务测试的 12 项实用技术(第一部分)》和《微服务测试的 12 项实用技术(第二部分)》。

原文链接

Testing Microservices: 6 Case Studies With a Combination of Testing Techniques - Part 3

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/hCJkZ949VREC8lESxs9G
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券