HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

微服务的测试策略

  • 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:228451

评论

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

SBOM喊话医疗器械网络安全:别慌,我罩你!Part Ⅱ

安势信息

网络安全 SBOM 开源组件 医疗器械 医疗网安

Java注解编译期处理AbstractProcessor详解

石臻臻的杂货铺

Java

CDH安装与部署

乌龟哥哥

三周年连更

深入探讨Go语言中Semaphore信号量的机制原理

Jack

通过华为云ECS云服务器搭建安防视频监控平台

DS小龙哥

三周年连更

从五一的旅游热潮看,该如何实现数字文旅的转型升级?

加入高科技仿生人

低代码 旅游业 数字赋能

服务百万商家的系统,发布风险如何规避?微盟全链路灰度实践

TakinTalks稳定性社区

Bash 脚本中,特殊变量$0到底是什么?

wljslmz

bash Linux 三周年连更

音视频八股文(8)-- h264 AnnexB

福大大架构师每日一题

音视频 ffmpeg 流媒体

2023阿里云合作伙伴大会-主论坛回顾

科技pai

阿里云 伙伴大会 2023阿里云合作伙伴大会

大模型“涌现”的思维链,究竟是一种什么能力?

脑极体

人工智能

龙蜥社区 4 月度运营大事件回顾

OpenAnolis小助手

开源 运营 龙蜥社区 sig 月度回顾

人脸识别:现代科技与隐私保护的博弈

来自四九城儿

《流畅的Python》第二版上市了,值得入手么?

Python猫

Python

LoRA: 大语言模型个性化的最佳实践

Zilliz

Towhee 大语言模型

软件测试/测试开发丨Python装饰器常见报错信息、原因和解决方案

测试人

Python 软件测试 自动化测试 装饰器 测试开发

城市的智能进化,汇成数字中国的璀璨银河

脑极体

智慧城市

《底层逻辑2:理解商业世界的本质》

石云升

读书笔记 三周年连更

【民生证券】敏捷转型大步迈进!民生证券敏捷实践培训圆满结束!

嘉为蓝鲸

敏捷转型 民生证券

苹果商店上架流程_App上架苹果流程及注意事项

雪奈椰子

2023-04-28:将一个给定字符串 s 根据给定的行数 numRows 以从上往下、从左到右进行 Z 字形排列 比如输入字符串为 “PAYPALISHIRING“ 行数为 3 时,排列如下 P

福大大架构师每日一题

Go 算法 rust 福大大

算法题每日一练:螺旋矩阵 I

知心宝贝

数据结构 算法 前端 后端 三周年连更

极速上手使用Docker,这篇文章就够了!

浅羽技术

Java Docker centos 容器化 三周年连更

程序员真的要失业了?新技术潮如何改变我们的职业生涯? | 社区征文

一道圣光

职业成长 ChatGPT 三周年征文

Go 方法接收器:选择值接收器还是指针接收器?

陈明勇

Go golang 方法 三周年连更 方法接收器

挑战 30 天学完 Python:Day14 高阶函数

MegaQi

挑战30天学完Python 三周年连更

语义分割标注:从认知到实践

来自四九城儿

我们如何将 Amazon Snowcone 送入轨道

亚马逊云科技 (Amazon Web Services)

云服务规划技术

阿泽🧸

云服务 三周年连更

智能公厕设备升级方案@光明源智慧公厕

光明源智慧厕所

智慧城市

什么是对象存储?对象存储的原理是什么?有哪些开源的、非开源的对象存储服务?

Java架构历程

对象存储 三周年连更

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