写点什么

苏宁 MOCK 测试桩服务建设实践

  • 2018-08-20
  • 本文字数:5148 字

    阅读完需:约 17 分钟

前言   

2018 年苏宁易购提出了智慧零售大开发战略,今年将新开 5000 家门店,到 2020 年,线下门店总数达 2 万家。半年来,以急速推进的大开发战略高超迭起,店面实现从城市到县镇市场全面覆盖,使得消费者在任何时间、任何地点、任何服务的需求都可以得到满足。

这样的发展速度对苏宁的 IT 技术提出了更高的要求,其中一个重要的环节就是加快软件版本的上线步伐,伴随着软件的上线必然存在巨大的测试压力,在敏捷过程中,苏宁测试遇到了如下困境:

  1. 依赖方不可用,测试人员无法提前介入测试;
  2. 数据构造,复杂的场景或者特殊的数据,无法很快生成,导致场景无法覆盖;
  3. 异常模拟;
  4. 外部系统不可用,或者没有对应的测试环境,或者需要现金交易;
  5. 压测时,依赖方性能较差,无法保证本系统性能最优;全链路压测时,无法限定链路范围;

为了提高生产效率和测试覆盖率,苏宁蛙测平台上线全场景 Mock 桩服务解决方案,支持 HTTP、ESB、RPC 等协议 Mock,支持同步、异步以及回调场景等功能,成功解决测试人员、开发人员在测试和研发过程中,数据构造、环境依赖等痛点,大大提高了生产效率,提高测试场景的覆盖率,保障了业务版本上线的质量。目前蛙测 Mock 服务应用于苏宁 100+ 中台、后台系统,服务了 1000+ 万次桩服务调用,在苏宁各个测试产品线得到了广泛的应用。具备的能力如下:

实践过程及应用效果

第一阶段:Mock1.0 从无到有过程

当初,苏宁并没有一套通用的 MOCK 服务能力,各个业务线基本是由开发人员,在应用代码中,植入 Mock 逻辑,由测试人员在应用外部统一针对特定接口进行预埋桩响应内容,这样的方案给开发和测试带来了很大的工作量,开发人员需要在版本迭代过程中,不断维护 Mock 逻辑,同时也污染了应用代码,很容易把 Mock 逻辑发布到生产坏境,增加上线的风险。所以,迫切的需要一套通用的 Mock 服务能力。基于这样的问题,苏宁蛙测服务平台,通过收集各个产品线 Mock 需求、分析,开始从 0 到 1 建设一站式 Mock 服务能力,实现代码无侵入式的通用 Mock 服务桩,也就是 Mock1.0 版本,整体思路是与中间件打通,组件识别 Mock 的标识,将请求路由到 MockService 上,实现千人千面的 Mock 服务:

正常请求

而由测试工具发起的请求(HTTP、ESB、RPC 等),首先测试人员会在本地预埋 Mock 响应内容,同时启动本地 MockService,在发起 Mock 请求时会生成的 Mock 标识,Mock 请求到达被测系统 A 时,相应组件会识别此 Mock 标识,将依赖方的请求转发到 MockService 上,大致思路如下:

Mock 请求

Mock 标识如何传递:

  1. RPC 类型:内部 Java 远程调用框架 RSF,在测试工具模拟服务消费方,发起 RSF 请求时,会附带本次请求中需要 Mock 的后端依赖方,以 Attachement 方式附带到 RSF 服务方,在服务方应用中,RSF 组件会进行识别、路由,RSF 中间件请求完成后,进行 Mock 信息清理;
  2. HTTP/ESB 类型:被测应用在打包或者 CD 发布时,手动或者自动在 web.xml 中配置中增加 Mock 的 filter 过滤器,在 doFileter 方法中,如果识别到 HTTP 请求头中包含 Mock 标识,则将 Mock 信息设置到中间件中,在中间件发起依赖方 HTTP 请求时,进行 Mock 识别、转发,请求结束后,清理本次请求的 Mock 信息;

测试工具如何埋桩

一次 RPC 的调用,可能涉及多个后端依赖系统服务调用,所以,在工具脚本设计时,增加了步骤 Group 概念。把本次一次调用过程中,需要 Mock 的调用,放在一个 Group 下,在发起请求时,把 Group 下的 Mock 步骤,打成多个 Mock flag 标识,供 RPC 组件中 Mock 识别模块识别,交互如下:

在 MockService 服务上,还支持匹配规则,根据匹配规则,响应不同内容。

在 Mock1.0 服务中,仅支持 RPC、HTTP、ESB 同步类型、基于单次请求级别的 Mock 调用,测试人员在本地用测试工具进行发起请求,每个测试工具都作为一个独立的 MockService 存在,达到互不干扰、千人千面的效果,同时业务方系统无需植入 Mock 代码,即可支持 Mock 能力,大大减少开发工作量和发布上线风险。

随着 Mock 功能深入开展,基于请求级别的 Mock 还远远不能完全满足业务测试场景,尤其是后台系统,测试人员在实际使用过程中,又遇到如下困难:

  1. 多线程、Job 等异步方式发起后端依赖方请求,尤其应用自己实现的多线程逻辑时,请求的调用链路会断开,导致 Mock 标识无法传递;
  2. 被测应用的一次调用过程,往后端系统同一个接口,发起多次不同参数的请求,无法得到不同的 Mock 响应;
  3. 实际测试场景中,存在回调过程,无法模拟;
  4. 请求从 UI 层面发起时,无法生成 Mock 标识;

为了解决测试的痛点,提高测试覆盖率,蛙测平台将 Mock1.0 进行功能扩展,推出了全局桩、UI 桩、回调桩等功能,也就是 Mock2.0 版本。

第二阶段:Mock2.0 从局部到全面过程

在 Mock1.0 版本中,仅支持请求级别的 Mock 功能,而在 Mock2.0 版本中,Mock 能力将从请求级扩展到全局桩、UI 桩、回调桩等全面桩,解决测试过程中,所涉及的 Mock 需求。

全局桩

全局桩功能是为了解决异步、多线程等测试场景,整体思路是:测试人员事先一次性的将需要 Mock 的依赖方接口信息,刷入被测系统 JVM 内存中,这些 MOCK 信息,全局生效,当请求中没有附带 Mock 标识时(请求可能由页面触发、也能由其他测试工具触发),被 Mock 的后方接口,一律走全局桩服务,当请求中附带 Mock 标识时,请求级 Mock 优先级高于全局桩 Mock。

UI 桩

UI 桩主要应用于是分层测试设计中,通过分层、解耦,可以简化问题,针对有明确分层设计的系统,在层与层之间验证接口的正确性。比如:Web、APP UI 层面,可以适当介入 Mock,将关键接口 Mock 掉,达到 UI 验证的目的,而后端接口,通过接口方式进行场景验证,从而达到分层测试目的。UI 桩设计思路如下:

测试工具可以自动将本地浏览器代理、手机代理设置为 Proxy 服务地址,同时,根据规则,监听前后交互请求,测试人员可以选择录制生成自动化脚本,还可以根据规则篡改、响应等等,达到前后分离测试目的,还能屏蔽后端服务或者接口,对边界值、等价类划分等数据进行模拟,提高测试场景覆盖。

测试工具提供简单的 GUI 操作,具体如下:

启动代理

生成步骤

埋桩

回调桩

在实际系统交互中,还存在这样的场景:后方依赖服务响应比较慢,在高并发场景下,调用方会积压大量的线程阻塞等待依赖方的返回结果,导致调用方资源被耗尽,产生严重后果,为了解决这种场景,业务方一般采用异步回调方式来解决。为了模拟异步回调测试场景,Mock 能力也扩展了回调功能,模拟后方系统结果返回、延迟回调等场景,从而达到测试目的。

第三阶段:从自动化到压测挡板过程

从第一阶段的请求级桩到全局桩,桩的服务能力不断增强,不断满足测试产品线各类业务场景,主要针对功能的验证,模拟依赖方的返回,并结合自动化工具,固化成脚本,达到复用的目的。但在性能测试过程中,期望对 Mock 还需具备压测挡板的能力,问题如下:

  1. 在跨系统的性能测试中,由于客观因素的限制,如:测试资源有限、后端系统不具备压测条件、后端系统性能不达标等,导致无法线下压测被测系统性能;
  2. 全链路压测过程中,无法屏蔽外部依赖系统和限定链路范围;
  3. 线下压测过程中,很难模拟在后端应用不同性能下,比如:延迟设置 0.5s、1s 甚至 2s 的不同延迟,考察被测应用在不同的延迟情况下的性能表现。

为了解决以上压测过程中问题,蛙测推出了基于热插拔方式压测挡板服务,主要解决了压测过程中,模拟依赖应用性能,比如:TPS、响应延迟等,具备能力如下:

  • 支持热插拔,随时可以终止 MockFilter 服务,提高了系统对灾难的及时恢复能力、扩展性和灵活性;
  • 支持消费端挡板,桩信息一次性刷入被测应用 jvm 中,被 Mock 的后端服务,直接从消费端内存中直接获取并返回,模拟延迟等,此 Mock 请求直接从被测应用的服务器内拿 Mock 响应;
  • 支持服务端挡板,桩服务由蛙测平台额外独立提供,根据用户设定的性能 TPS 指标,动态计算需要多少 Mock 服务线程以及多少台 Mock 服务节点,并把响应的 Mock 信息一次性刷入到 Mock 服务器中,供本次压测使用,此 Mock 请求从被测应用服务器外部拿 Mock 响应;

为什么要区分消费端挡板和服务端挡板呢?主要是在实际应用中,尤其生产环境的压测,并没有那么多的 Mock 服务器资源供挡板调用,而消费端挡板恰恰解决了这一问题,充分利用被压应用服务器资源,压测预热前,一次性刷入需要 Mock 的后端应用服务,压测过程中,通过各个中间件进行 MockFilter,决定后端调用是 Mock 调用还是真实调用,是消费端 Mock 还是服务端 Mock。

消费端挡板整体思路

服务端挡板整体思路:

蛙测挡板创建

消费端 VS 服务端挡板压测结果对比

  • 压测目的:消费端挡板与服务端挡板性能对比
  • 机器 4C 8G
  • 场景:被 Mock 系统模拟桩数 1 万条

从压测对比中,得出结论:消费端挡板性能表现远远的高于服务端挡板,但相应的对于服务端资源消耗占比较高。针对以上数据对比,并结合实际业务场景压测需求,可择优选择合适的挡板方案。

结语   

蛙测的 Mock 服务能力从最初的请求级、千人千面的 Mock 到全局桩能力,从手工测试到自动化测试再到压测挡板,不断的探索、提升测试过程中的效能。未来,我们还会在字节码层面进行线上录制,转化成自动化脚本,回放到测试环境,Mock 掉必要的依赖调用等,达到线上录制回放的目的,在测试技术方向,蛙测团队将会继续努力探索,永不停歇!

作者简介

程派峰,苏宁易购测试平台高级技术经理,2013 年加入苏宁,一直从事测试工具与平台的研发工作。具备广泛的技术视野和很强的技术前瞻性,了解新技术、新趋势,擅长自动化测试技术创新。对各种开源框架有了解,并具备良好的落地实践,目前专注于工程效能及质量提升工作。

感谢张婵对本文的审校。

2018-08-20 18:103966

评论 1 条评论

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

2022年中国消费金融行业数字化技术创新分析

易观分析

消费金融

程序培训哪里比较好,应该怎么去选择

小谷哥

去摩尔纹不用再凹姿势拍照了!合合信息智能文字识别“黑科技”上线扫描全能王

合合技术团队

人工智能 摩尔纹

【10.21-10.28】写作社区优质技术博文回顾

InfoQ写作社区官方

优质创作周报

数据可视化大屏酷炫秘籍之前端开发者自己动手

葡萄城技术团队

前端 BI 可视化数据

前端开发培训学习那不难,怎么选择机构

小谷哥

2022创业邦100未来独角兽评选正式启动!

创业邦

数据库浅析

Andy

“程”风破浪的开发者|架构师的思维转变

CTO技术共享

学习方法 架构师 “程”风破浪的开发者

【web 开发基础】PHP中的特殊流程控制(break) -PHP 快速入门 (20)

迷彩

break 10月月更 web开发基础 PHP基础

阿里云PolarDB、RDS获评信通院数据库Serverless认证最高“先进级”

极客天地

Wallys/QCN9074 11ax 4x4 MU-MIMO 2.4G M.2 /2.4GHz, max 23dBm per chain, up to 1147Mbps //QCN9072/QCN9024

wallys-wifi6

IPQ6010 IPQ6000

牛掰!阿里十年架构师总结的分布式原理、设计与实战笔记

小小怪下士

Java 程序员 面试 分布式

数字政府行业趋势洞察报告(2022年)解读

信通院IOMM数字化转型团队

数字政府 IOMM 政府数字化转型

前端培训适合零基础学习吗

小谷哥

转行大数据培训怎么样

小谷哥

Groovy Swagger @requestBody 加载超时 一键搞定

FunTester

Baklib知识分享|文档管理促进企业成长进步

Baklib

文档管理

中台“不火”了,企业“底座”却火了

BeeWorks

千企千面,WorkPlus面向政企提供个性化的数智办公平台解决方案

BeeWorks

【web 开发基础】PHP 中的特殊流程控制(continue) -PHP 快速入门 (21)

迷彩

continue 10月月更 循环控制 PHP基础

专项贴息贷款加速投放 锋云智慧助力教育信息化乘风而上

千锋IT教育

CSP 直通车 | 在线直播认证培训双周末班 火热报名中

ShineScrum

敏捷教练 ScrumMaster认证 Scrum认证

5000字解读《低代码发展白皮书(2022年)》

信通院IOMM数字化转型团队

低代码 无代码 低代码报告 IOMM

“程”风破浪的开发者|Web 3.0 是泡沫还是金矿?

架构精进之路

1024 Web3.0 “程”风破浪的开发者

即时通讯IM WorkPlus支持国产化信创环境

BeeWorks

大数据培训学习应该储备什么知识

小谷哥

多线程、多进程同时操作MMAP,会怎么样?

C++后台开发

多线程 后端开发 多进程 linux开发 C++开发

大咖说·对话开源|论数据库开源人才培养的实践

大咖说

数据库 阿里云 开源 人才培养

MySql浅析

Andy

“程”风破浪的开发者|CTO浅谈数字化转型

CTO技术共享

学习方法 CTO 数字化转型 “程”风破浪的开发者

苏宁MOCK测试桩服务建设实践_软件工程_程派峰_InfoQ精选文章