50万奖金+官方证书,深圳国际金融科技大赛正式启动,点击报名 了解详情
写点什么

微服务的测试策略

  • 2022-09-13
    北京
  • 本文字数:4055 字

    阅读完需:约 13 分钟

微服务的测试策略

微服务应用程序是一组通过网络进行通信的分布式程序,有时也会与第三方服务和数据库交互。微服务是网络化的,与传统的单体应用程序相比,它的故障点更多。为此,我们需要一种不同的、涉及面更广的测试方法。那么,我们该如何测试一个微服务应用程序?测试金字塔还有效吗?当涉及到第三方服务并可能出现网络中断时,我们该如何测试?在这篇博文中,我们将尝试回答所有这些问题。


本文最初发布于 semaphore 博客。


微服务应用程序是一组通过网络进行通信的分布式程序,有时也会与第三方服务和数据库交互。微服务是网络化的,与传统的单体应用程序相比,它的故障点更多。为此,我们需要一种不同的、涉及面更广的测试方法。


那么,我们该如何测试一个微服务应用程序?测试金字塔还有效吗?当涉及到第三方服务并可能出现网络中断时,我们该如何测试?在这篇博文中,我们将尝试回答所有这些问题。


微服务测试面临的挑战


微服务架构是一种意义深远的范式变迁,我们必须重新考虑传统的测试技术。与经典的单体架构相比,微服务在许多方面都有所不同:


  • 分布式:微服务部署在多台服务器上,地理位置可能也不一样,这会增加延迟,而且会受网络中断所影响。测试要依赖网络,即使代码没问题,也可能会失败,导致 CI/CD 管道中断,开发受阻。

  • 自治:只要不破坏 API 兼容性,开发团队就可以随时部署他们的微服务。

  • 测试区域扩大:每个微服务都至少会暴露数个 API 端点,因此,测试覆盖面要更大。

  • 多语言:开发团队可以选择最适合其微服务的语言。在一个大型系统中,可能无法找到一个适用于所有组件的测试框架。

  • 产品是一个活动目标:由于微服务是由自治团队单独部署和构建,所以需要额外的检查和边界,以确保它们部署后仍然可以正常运行。


所有这些特点都让我们不得不考虑新的测试策略。


微服务测试金字塔


测试金字塔是自动化软件测试的规划工具。传统的金字塔包含 3 种类型的测试:


  • 单元测试

  • 集成测试

  • 端到端测试。


微服务金字塔新增了两种类型:组件契约测试



这是微服务测试金字塔的一个版本。其他版本可能顺序上会有所不同。有些版本可能将契约测试包含在了集成层。事实上,金字塔更多的是一份指南,而非一成不变的东西。


接下来,我们将对金字塔的每一层做进一步的介绍。


微服务的单元测试


单元测试是粒度最小(数量最多)的测试形式之一。单元由可以单独测试的类、方法或函数组成。单元测试是开发实践中不可分割的一部分,比如测试驱动开发或行为驱动开发。


与单体相比,微服务中的单元可能更需要通过网络调用来完成其功能。这时候,我们可以让代码访问外部服务——就得接受延迟和不确定性,也可以调用测试替身,因此,我们有如下两种处理微服务依赖的方法:


  • 独立单元测试(Solitary unit tests):如果我们需要测试结果始终是确定的,就应该使用这种方法,通过模拟(mocking)或存根(stubbing)来隔离要测试的代码和外部依赖。

  • 社交单元测试(Sociable unit tests):社交测试允许调用其他服务。在这种模式下,我们把测试的复杂性推到了测试或过渡环境。社交测试是非确定性的,但如果测试通过,我们对结果会更有信心。



我们可以使用测试替身独立运行单元测试。我们也可以让要测试的代码调用其他微服务,这就是我们正在讨论的社交测试。如你所见, 可信度与稳定性之间的平衡将贯穿本文始终。模拟可以加快测试速度,降低不确定性,但模拟越多,测试结果的可信度就越低。虽然也有缺点,但社交测试更实用。因此,你要在这两种类型的测试之间做好权衡取舍。


如果你想实际看下独立测试和社交测试的例子,可以读一下 Dylan Watson 在 dev.to 上发表的那篇不错的博文。


微服务的契约测试


当两个服务通过接口耦合时,契约就形成了。契约详细列出了所有可能的输入、输出及其数据结构和副作用。服务的消费者和生产者必须遵守契约描述的规则才能进行通信。


契约测试可以保证微服务遵守契约。它们不会全面测试服务的行为;它们只确保输入和输出具备期望的特性,服务执行时间和性能都在可接受的范围内。


契约测试可以由生产者运行,也可以由消费者运行,还可以两者都运行,这取决于服务之间的关系。


  • 消费者端契约测试由下游团队编写并执行。测试时,微服务连接到生产者服务的模拟版本,检查它是否可以消费其 API。

  • 生产者端契约测试在上游服务中运行。这类测试会模拟客户端可以发起的各种请求,验证生产者是否符合契约。生产者端测试让开发人员可以知道他们什么时候会破坏消费者兼容性。



契约测试可以在上游或下游运行。生产者端测试可以检查服务变更是否会给依赖它的服务造成破坏。消费者端测试使用上游生产者的模拟版本(并非真正的生产者服务)来运行消费者端组件,验证消费者是否可以发起请求,并消费生产者提供的期望响应。我们可以使用类似 wiremock 这样的工具来再现 HTTP 请求。如果两端都通过了契约测试,那么生产者和消费者就是兼容的,应该能够通信。持续集成时应该总是运行契约测试,以便在部署前发现不兼容的情况。


你可以在 Pact 的 5 分钟入门指南里在线试用契约测试。Pact 是一个基于 HTTP 的测试工具,可以编写和运行基于消费者或是生产者的契约测试。


微服务的集成测试


微服务的集成测试方式与其他架构略有不同,其目标是通过微服务交互来识别接口缺陷。与契约测试总有一端是模拟的不同,集成测试使用真实服务。


集成测试不关注服务的行为或业务逻辑。集成测试是为了确保微服务可以与其他微服务以及自己的数据库交互。我们希望通过集成测试来发现类似 HTTP 头缺失、请求 / 响应对不匹配这样的问题。因此,集成测试通常在接口层实现。



使用集成测试来检查微服务是否可以与其他服务、数据库和第三方端点通信。建议读下 Vitaly Baum 关于微服务存根的博文,看下实际的集成代码测试。


微服务的组件测试


组件是一个较大的系统中可以完成一项职责的一个微服务或一套微服务。


组件测试是验收测试的一种,使用模拟资源或 mocking 来替换服务,孤立地检查组件的行为。


组件测试比集成测试更全面,它们既会测试快乐路径,也会测试不快乐路径——例如,测试组件如何响应模拟网络中断或恶意请求。我们想知道组件是否满足其消费者的需求,很像我们在验收测试或端到端测试中所做的那样。



组件测试执行一组微服务的端到端测试。超出组件范围的服务都是模拟的。


执行组件测试的方法有两种:进程内和进程外。


进程内组件测试


在组件测试的这个子类中,测试执行器在和微服务相同的线程或进程内。我们以“离线测试模式”启动微服务,所有的依赖都是模拟的,这让我们无需网络就可以运行测试。



组件测试在和微服务相同的进程内运行。测试在适配器中注入一个模拟服务,以模拟与其他组件的交互。


进程内测试仅适用于组件是单个微服务的情况。乍看之下,组件测试和端到端测试或验收测试非常类似。唯一的区别是,组件测试只选取系统的一部分(组件),并将其与其余部分隔离开来。它会对这个组件做全面的测试,以验证它是否提供了用户或消费者需要的功能。



组件测试和端到端测试可能看上去类似。但区别在于,端到端测试在一个类生产环境中测试整个系统(所有微服务),而组件测试只隔出系统的一部分进行测试。两种测试都会从用户(或消费者)的角度来检查系统行为,模拟用户可能执行的操作。我们可以使用任何语言或框架来编写组件,但最流行的可能要数 Cucumber 和 Capybara 了。


进程外组件测试


进程外测试适用于任意大小的组件,包括由许多微服务组成的组件。在这类测试中,组件被(原封不动地)部署在一个测试环境中,所有的外部依赖都是以模拟或存根方式提供。



在这类组件测试中,测试环境会比较复杂,因为它要模拟系统的其余部分。


要全面了解契约测试的概念,建议研究下 Java Spring 契约测试的示例代码。此外,对于 Java 开发人员,这篇博文提供了一些在各个层面测试 Java 微服务的代码样例。


微服务的端到端测试


到目前为止,我们都是分块测试系统。单元测试用于分别测试微服务的各个部分,契约测试验证 API 兼容性,集成测试检查网络调用,组件测试用于验证子系统的行为。只有在自动化测试金字塔的最顶端,我们才是对整个系统进行测试。


端到端(E2E)测试用于确保系统可以满足用户需求并实现其业务目标。E2E 套件应该覆盖应用程序的所有微服务,并且使用与用户相同的界面——通常搭配 UI 和 API 测试。


应用程序的运行环境应尽量接近生产环境。在理想情况下,测试环境中应包含应用程序通常需要的所有第三方服务,但有时候,为了降低成本或防止滥用,也可以模拟。



端到端测试是模拟用户交互的自动化测试。只有外部第三方服务可以是模拟的。


从测试金字塔可以看出,E2E 测试数量最少,这很好,因为它们通常最难运行,也最难维护。只要专注于用户的操作过程及需求,我们就可以从少数几个 E2E 测试中获得很大的价值。


小结


范式变了,策略也要跟着变。在微服务架构下,测试比以往任何时候都重要,但我们需要调整技术来适应新的开发模型。系统不再是由单个团队管理。取而代之,每个微服务的所有者都必须完成好自己的部分,才能保证整个应用程序的正常运行。


有些组织可能会认为,单元、契约和组件测试已经足够了。其他的则认为需要端到端和集成测试,他们可能会选择组建一支 QA 团队,以推动跨团队的测试。


想要进一步了解微服务吗?可以阅读以下几篇文章:


  • 什么是微服务架构?


https://semaphoreci.com/blog/microservice-architecture


  • 微服务架构的领域驱动设计原则


https://semaphoreci.com/blog/domain-driven-design-microservices


  • 微服务的发布管理


https://semaphoreci.com/blog/release-management-microservices


  • 转向微服务之前要了解的 12 种单体架构优化方法


https://semaphoreci.com/blog/monolith-microservices


感谢阅读!


原文链接:


https://semaphoreci.com/blog/test-microservices


今日好文推荐


对峙数年后,微软对 Java 的态度 180°大反转


奇葩事儿:删除用户做数据还无法恢复,只赔 3 万;微信键盘来了,体积 524MB;谷歌希望将效率提高 20%:暗示将裁员?| Q 资讯


“不搞职级、人人平等” 25 年后行不通了?Netflix 破天荒引入细分职级:气走老员工


缺少软件开发文化,大众汽车陷入困境,CEO 也被赶下了台


2022-09-13 20:228917

评论

发布
暂无评论
发现更多内容

Parallels Desktop 19 for Mac(PD19虚拟机)无需关闭sipv19.1.0一键激活版

Rose

Cornerstone意外退出的解决方法 Cornerstone 4.2永久激活版 Mac SVN工具

Rose

理解 gRPC 与 REST:选择适合您项目的最佳 API 方案

Liam

程序员 gRPC 后端 Rest API

使用css制作心形图案并且添加动画心动效果

源字节1号

开源

火山引擎数据飞轮升级实验平台架构,解决人效与成本问题

极客天地

华为大咖说 | 数字时代的财富秘诀:数据资产化全攻略

华为云 资产管理

Bonree ONE赋能汽车行业 重塑可观测性体验

博睿数据

Axure RP教程(Axure RP中文授权码),如何查看和共享您的原型?

Rose

【永久密钥】VMware Fusion Pro 13 for Mac(VM虚拟机)v13.5.0激活版

Rose

macOS Sequoia 15(Macos15系统)v15.0 Beta 3测试版本

Rose

NTFS磁盘格式读写工具 Tuxera 2022 mac注册版 及破解教程

Rose

数据驱动运维:如何通过可观测性实现AIOps的突破

雅菲奥朗

运维 可观测性 AIOPS Observability 人工智能运维

深入了解 DN-404:引领 NFT 市场的创新标准

NFT Research

NFT\ web3、 ERC404

Macs Fan Control Pro风扇预设介绍 Macs Fan Control Pro mac风扇转速和温度

Rose

新手必看!sublime text 快捷键大集合

Rose

腾讯云大数据连续三年蝉联中国大数据市场领导者象限

腾讯云大数据

腾讯云 大数据

AIOps:解决企业IT挑战的智能利器

雅菲奥朗

运维 可观测性 AIOPS SRE

解决 SecureCRT中文乱码方法(附SecureCRT mac永久注册码)

Rose

跨平台的SSH、Telnet和SFTP客户端 Termius for Mac v8.4.0激活版

Rose

微服务的测试策略_架构_Tomas Fernandez_InfoQ精选文章