如何进行微服务的集成测试
集成测试的概念
说到集成测试,相信每个测试工程师并不陌生,它不是一个崭新的概念,通过维基百科定义可以知道它在传统软件测试中的含义。
Integration testing (sometimes called integration and testing, abbreviated I&T) is the phase in software testing in which individual software modules are combined and tested as a group. Integration testing is conducted to evaluate the compliance of a system or component with specified functional requirements.
即,集成测试(有时称为集成和测试,简称 I&T)是软件测试中的阶段,在该阶段中,将各个单独开发的软件模块组合在一起并进行整体测试,以便评估系统或组件是否符合指定的功能要求。
微服务架构下也需要集成测试,需要针对不同服务的不同方法之间的通信情况进行相关测试。因为在对微服务进行单元测试时,单元测试用例只会验证被测单元的内部逻辑,并不验证其依赖的模块。即使对于服务 A 和服务 B 的单元测试分别通过,并不能说明服务 A 和服务 B 的交互是正常的。
对于微服务架构来说,集成测试通常关注于验证那些与外部组件(例如数据存储或其他微服务)通信的子系统或模块。目标是验证这些子系统或模块是否可以正确地与外部组件进行通信,而不是测试外部组件是否正常工作。因此,微服务架构下的集成测试,应该验证要集成的子系统之间与外部组件之间的基本通信路径,包括正确路径和错误路径。
微服务架构下的集成测试
如上图所示,网关组件层(Gateways+Http Client+External Service)包含了访问外部服务的逻辑,通常包含一个 HTTP/S 的客户端,客户端会连接到系统中另一个微服务或外部服务。数据持久层(Date Mappers/ORM)用于连接外部数据存储。
即,微服务架构下的集成测试主要包括两部分:
网关组件层, 微服务的组件与外部服务的通信路径;
数据持久层, 数据库访问模块与外部数据库的交互。
这里请注意,因为需要测试微服务下子系统之间的通信和外部服务的通信是否正确,所以理想情况下不应该对外部组件使用测试替身(Test Double)。
下面我们逐一来看这两部分是如何进行集成测试的:
(1)网关组件层集成测试

假设有个登录服务,该服务需要知道当前时间,而时间是由一个外部的时间服务提供的。当向 /api/json/cet/now 发出 GET 请求时,状态码为 200,并返回如下完整的时间信息。
{
$id: "1",
currentDateTime: "2020-07-29T02:11+02:00",
utcOffset: "02:00:00",
isDayLightSavingsTime: true,
dayOfTheWeek: "Wednesday",
timeZoneName: "Central Europe Standard Time",
currentFileTime: 132404622740972830,
ordinalDate: "2020-211",
serviceResponse: null,
}
如果访问的 URL 错误,比如向 /api/json111/cet/now发出 GET 请求时,状态码为 404,返回如下错误提示。
一般来说,集成测试会负责检验与外部服务的连接以及交互协议相关的问题,如 HTTP header 的缺失、SSL 处理的异常,或者请求/响应的不匹配。所有的错误处理逻辑都需要在测试中被覆盖,以确保所使用的服务和协议客户端在特殊情况下能够按预期进行响应。
(2)数据持久层集成测试
数据持久层的集成测试则要复杂一些,因为结果会被保存在存储系统上并被持久化,每次测试的执行都可能因为更改了数据而对后续测试的执行产生影响。这意味着,两次测试之间并非完全独立,因为它们操作了共同的数据。
绝大多数情况下,应该保证两次测试之间的外部因素也是相互独立的。因为这样的错误(测试数据的修改而导致的测试执行失败)出现后往往很难意识到,进而影响排查进度。
为了保障两次测试的独立性,持久层集成测试的常见步骤是:
-
在执行任意测试前,先回退数据库到一个已知且可预测的状态,这需要清理/回滚之前对数据库的修改;
-
通过插入对测试来说已知且预期中的数据来重建数据库;
-
进行相关的测试;
-
循环上述这个过程。

常见问题及解决策略
然而,有很多时候外部服务不可用(服务尚未开发完成、服务有 block 级别的缺陷未修复),或其异常行为(如外部组件的超时、响应变慢等)很难去验证。外部组件不能使用测试替身,外部服务又不可用或异常场景难构造,看似无解,实际上都是有替代方案的。
服务不可用
针对服务不可用的情况,微服务虚拟化技术可以完美解决这种问题,它是避免与其他服务通信时出现意外的必要工具,在具有大量依赖项的企业环境中工作的时候更是如此。它可以用于在测试阶段消除对第三方服务的依赖,测试应用程序在遇到延迟或其他网络问题时的行为。它通过创建代理服务实现对依赖服务的模拟,特别适合测试服务之间的通信。常见的工具有 Wiremock、Hoverfly、Mountebank 等。
以 Wiremock 为例,如下代码的效果是:当相对 URL 完全匹配 /api/json/cet/now 时,将返回状态 200,响应的主体类似于 /api/json/cet/now的返回值,Content-Type Header 的值为 text/plain。否则,当相对 URL 错误,比如访问 /api/json111/cet/now 时,则返回 404 的错误。
@Test
public void exactUrlOnly() { stubFor(get(urlEqualTo("/api/json/cet/now")) .willReturn(aResponse() .withHeader("Content-Type", "text/plain") .withBody(equalToJson("{ $id: \"1\", currentDateTime: \"2020-07-29T02:11+02:00\", utcOffset: \"02:00:00\", isDayLightSavingsTime: true, dayOfTheWeek: \"Wednesday\", timeZoneName: \"Central Europe Standard Time\", currentFileTime: 132404622740972830, ordinalDate: \"2020-211\", serviceResponse: null, }")))); assertThat(testClient.get("/api/json/cet/now").statusCode(), is(200)); assertThat(testClient.get("/api/json111/cet/now").statusCode(), is(404));
}
服务超时&响应慢难构造
如果使用真实服务测试,服务超时或响应慢等情况需要特殊构造下,这时候借助各种工具会比较方便,比如常见的软件有 Fiddler、Dummynet、Clumsy 等。
Wiremock 也支持延迟的功能,比如使用 withFixedDelay() 可以实现固定延迟的效果:
stubFor(get(urlEqualTo("/api/json/cet/now")).willReturn( aResponse() .withStatus(200) .withFixedDelay(2000)));
使用 withLogNormalRandomDelay() 可以实现随机延迟效果:
stubFor(get(urlEqualTo("/api/json/cet/now")).willReturn( aResponse() .withStatus(200) .withLogNormalRandomDelay(90, 0.1)));
数据初始化和构造的成本高
上述对数据持久层集成测试的方法虽然通用,但是将数据库进行初始化需要编写大量的样例代码,插入预期的数据也需要编写大量的数据库操作语句。面对这个问题,可以使用一些现成的持久化测试框架来改善测试体验,常见的持久化测试框架有 NoSQLUnit、DBUnit 等。
DBUnit 的设计理念就是在测试之前,先备份好数据库,再给对象数据库植入需要准备的数据,在测试完毕后,再读入备份数据库,初始化到测试前的状态。DBUnit 可以在测试用例的生命周期内来对数据库的操作结果进行比较。DBUnit 支持的数据库有 db2、h2、mssql、mysql、oralce、postgresql 等。
NoSQLUnit 是用 DBUnit 类似的方式来编写 NoSQL 数据库的测试。支持多种 NoSQL 数据库,包括 HBase、MongoDB、Redis、ElasticSearch、Vault、Neo4j 等。
总结
本节课讲解了微服务架构下的集成测试定义,接着讲解了微服务下的集成测试的两个方面:网关组件层集成测试和数据持久层集成测试。
在网关组件层集成测试中,通过服务虚拟化技术来实现对外部服务能力的模拟,通过模拟网络异常情况来构造外部服务超时、响应慢的情况。
在数据持久层集成测试中,通过持久化测试框架可以避免常规持久化测试时编写大量代码和大量 SQL 语句的情况。
当然,如上框架和工具的威力不限于此,文中只给出了关键的示例信息,你可以根据需求或兴趣自行探索学习。
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
软件测试面试小程序
被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!
涵盖以下这些面试题板块:
1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux
6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
相关文章:
如何进行微服务的集成测试
集成测试的概念 说到集成测试,相信每个测试工程师并不陌生,它不是一个崭新的概念,通过维基百科定义可以知道它在传统软件测试中的含义。 Integration testing (sometimes called integration and testing, abbreviated I&T) is the pha…...
spark grpc 在master运行报错 exitcode13 User did not initialize spark context
程序使用sparksql 以及protobuf grpc ,执行报错 ApplicationMaster: Final app status: FAILED, exitCode: 13, (reason: Uncaught exception: java.lang.IllegalStateException: User did not initialize spark context! 先说原因 : 1.使用了不具备权限…...
nginx 反向代理的原理
Nginx(发音为"engine X")是一个高性能、轻量级的开源Web服务器和反向代理服务器。它的反向代理功能允许将客户端的请求转发到后端服务器,然后将后端服务器的响应返回给客户端。下面是Nginx反向代理的工作原理: 1.客户端…...
【SpringBoot】第二篇:RocketMq使用
背景: 本文会介绍多种案例,教大家如何使用rocketmq。 一般rocketmq使用在微服务项目中,属于分模块使用。这里使用springboot单体项目来模拟使用。 本文以windows系统来做案例。 下载rocketmq和启动: RocketMQ 在 windows 上运行…...
飞天使-vim简单使用技巧
此文是记录技巧使用,如果想节约时间,可以直接看最后一个章节 vim 的介绍 vim号称编辑器之神,唯快不破,可扩展,各种插件满天飞。 vi 1991 vim 1.14 vim四种模式 普通模式: 移动光标, 删除文本,…...
分布式搜索引擎----elasticsearch
目录 1、初识elasticsearch 1.1、什么是elasticsearch 1.2.ELK技术栈 2、正向索引和倒排索引 2.1、正向索引 2.2、倒排索引 2.3、正向索引和倒排索引的区别 3、elasticsearch中的概念理解 3.1、文档和字段 3.2、索引和映射 3.3、mysql与elasticsearch 1、初识elasti…...
AnnotationConfigApplicationContext类和ClasspathXmlApplicationContext类的区别?
在 Spring Framework 中,AnnotationConfigApplicationContext 和 ClasspathXmlApplicationContext 是两个不同的应用程序上下文实现,用于配置和管理 Spring Bean 容器。它们之间的主要区别在于配置的方式和使用场景。 1. **AnnotationConfigApplication…...
使用VSCode SSH实现公网远程连接本地服务器开发的详细教程
文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…...
Codeforces Round 894 (Div. 3)
还是打一下卡!!! (A,B,C) 目录 A. Gift Carpet 链接 : 题面 : 题目意思 : 思路 : 代码 : B. Sequence Game 链接 : 题面 : 编辑 题目意思 : 思路 : 代码 : C. Flower City Fence 原题链接 : 题面 : 题目意思 : 思路 : 代码 : A. Gift Carpet 链…...
ACL2023 Prompt 相关文章速通 Part 1
Accepted Papers link: ACL2023 main conference accepted papers 文章目录 Accepted PapersPrompter: Zero-shot Adaptive Prefixes for Dialogue State Tracking Domain AdaptationQuery Refinement Prompts for Closed-Book Long-Form QAPrompting Language Models for Lin…...
“R语言+遥感“水环境综合评价方法
详情点击链接:"R语言遥感"水环境综合评价方法 一:R语言 1.1 R语言特点(R语言) 1.2 安装R(R语言) 1.3 安装RStudio(R语言) (1)下载地址 &…...
数据结构之哈希
哈希 1. 哈希概念2. 哈希冲突3. 哈希冲突解决3.1 哈希表的闭散列3.2 哈希表的开散列 2. 哈希的应用2.1 位图2.2 布隆过滤器 哈希(Hash)是一种将任意长度的二进制明文映射为较短的二进制串的算法。它是一种重要的存储方式,也是一种常见的检索方…...
可视化绘图技巧100篇基础篇(七)-散点图(一)
目录 前言 适用场景 图例 普通散点图与可视化 曲线图 气泡图...
关于什么是框架
框架(Framework)是一个框子——指其约束性,也是一个架子——指其支撑性。 IT语境中的框架,特指为解决一个开放性问题而设计的具有一定 性的支撑结构。在此结构上约束可以根据具体问题扩展、安插更多的组成部分,从而更迅…...
iOS开发Swift-集合类型
集合基本类型:数组 Array (有序), 集合 Set (无序不重复), 字典 Dictionary (无序键值对) 1.数组 Arrays (1)数组的表示 Array<Element> [Element](2)创建空数组 var someInts: [Int] [] someInts.count //数组长度(3)带值数组 var…...
【keepalived双机热备与 lvs(DR)】
目录 一、概述 1.简介 2.原理 3.作用 二、安装 1.配置文件 2.配置项 三、功能模块 1.core 2.vrrp 3.check 四、配置双机热备 1.master 2.backup 五、验证 1.ping验证 2.服务验证 六、双机热备的脑裂现象 七、keepalivedlvs(DR) 1.作…...
C++笔记之静态成员函数可以在类外部访问私有构造函数吗?
C笔记之静态成员函数可以在类外部访问私有构造函数吗? code review! 静态成员函数可以在类外部访问私有构造函数。在C中,访问控制是在编译时执行的,而不是在运行时执行的。这意味着静态成员函数在编译时是与类本身相关联的,而不…...
最新SQLMap进阶技术
SQLMap进阶:参数讲解 (1)–level 5:探测等级。 参数“–level 5”指需要执行的测试等级,一共有5个等级(1~5级),可不加“level”,默认是1级。可以在xml/payloads.xml中看…...
【BurpSuite常用功能介绍】
BurpSuite的使用 1.运行BurpSuite 2.代理设置 打开软件后,我们第一件事就应该去调试软件和浏览器的代理,让BURP能够正常工作抓包 proxy--options,我端口默认使用8080 然后我们打开一个浏览器,进入代理设置 (注意一点࿰…...
Leetcode 108. 将有序数组转换为二叉搜索树
108. 将有序数组转换为二叉搜索树 分析 给定一个有序数组,要求转换为二叉搜索树。 数组是有序的,并且要求二叉树。 这里看到数组是有序的,马上想到二分,但是又不需要完全二分 实现。 再复习二叉搜索树的结构特点: 左…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

