写点什么

微服务的测试策略

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

评论

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

10份重磅报告 — 展望中国数字经济未来

阿里技术

研究报告

FinClip | 来了, 2022 年 7 月更新大盘点

FinClip

react高频面试题总结(一)

helloworld1024fd

React

【LeetCode】设计数字容器系统Java题解

Albert

LeetCode 8月月更

C++引用分析实例与案例刨析及使用场景分析详解

CtrlX

c c++ 后端 程序员进阶 8月月更

OSI 七层模型和TCP/IP模型及对应协议(详解)

Five

TCP/IP TCP协议 8月月更

8大软件供应链攻击事件概述

SEAL安全

开源 DevOps DevSecOps 软件供应链安全 软件供应链攻击

Geoffrey Hinton:深度学习的下一个大事件

OneFlow

人工智能 神经网络 深度学习

如何在技术上来保证LED显示屏质量?

Dylan

LED显示屏 led显示屏厂家

受邀出席Rust开发者大会|Rust如何助力量化高频交易?

非凸科技

量化策略 量化交易

DVWA 通关记录 2 - 命令注入 Command Injection

Todd-Lee

Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架

小周先生

开源 Vite2 vue3.0 #开源 8月月更

C++关于函数参数的分析与函数重载进阶教程

CtrlX

c++ 编程语言 后端 cpp 8月月更

一体化在线政务服务平台,小程序容器技术加速建设步伐

Speedoooo

小程序 小程序容器 政务平台

阿里云数据存储生态计划发布,助力伙伴数据创新

云桌派

阿里云

博云入选Gartner中国DevOps代表厂商

BoCloud博云

云计算 容器 DevOps 云原生 云平台

Maven中的scope

六月暴雪飞梨花

maven 开源 技术 8月月更 scope

React高频面试题合集(二)

helloworld1024fd

React

基于threejs的商品VR展示平台的设计与实现思路

Five

js vr three.js 签约计划第三季 8月月更

开源一夏 |Spring boot 自动配置原理

叶秋学长

开源 8月月更

重磅大咖来袭!阿里云生命科学与智能计算峰会精彩内容剧透

阿里云弹性计算

高性能计算 生命科学 AI制药 智能计算

爆款视频怎么做?这里或许有答案!

博文视点Broadview

“纯C”实现——三子棋小游戏

一介凡夫

c 后端、 #开源 8月月更

react常见面试题

helloworld1024fd

React

【云原生】jenkins部署docker镜像到远程服务器

青芒果

云原生 CODING Linxu docekr 8月月更

外包学生管理系统架构文档

松哥手把手教你在 Vue3 中自定义插件

江南一点雨

Java Vue

流动性质押挖矿系统开发如何制作?单双币系统开发成熟技术

开发微hkkf5566

小程序插件的生态丰富,加速开发建设效率

Speedoooo

小程序 小程序容器 小程序插件

半夜赶工制作简报的我好想说 : 确定了,最终稿就是这样

叶小鍵

阿里前端智能化技术探索和未来思考

阿里技术

前端 智能化

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