如何进行微服务的集成测试
集成测试的概念
说到集成测试,相信每个测试工程师并不陌生,它不是一个崭新的概念,通过维基百科定义可以知道它在传统软件测试中的含义。
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. 将有序数组转换为二叉搜索树 分析 给定一个有序数组,要求转换为二叉搜索树。 数组是有序的,并且要求二叉树。 这里看到数组是有序的,马上想到二分,但是又不需要完全二分 实现。 再复习二叉搜索树的结构特点: 左…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...

