携程Mock本地化实践

一、引言

这里说的Mock指的是系统测试或者接口测试场景下,模拟被依赖的其他服务接口进行响应返回的工具。测试人员通过服务接口级Mock的手段隔绝真实外部依赖,创造可控、稳定的测试运行环境,以提升问题的查全率和查准率。

然而,随着业务的发展和微服务化的进程,我们系统的结构越发的庞杂,Mock工具的实际效果开始变得差强人意。这里给大家分享我们遇到的挑战以及解决思路。

二、问题的出现

随着业务发展和微服务化进程,系统结构越发庞杂。服务化场景下使用Mock,有两个问题开始浮现出来。

1)工作串扰,启用Mock影响其他应用的测试工作

理想中的场景:

操作注册中心,使依赖指向Mock服务。

现实中的场景:

通过注册中心切换被测应用的依赖指向到Mock服务的动作,同样会影响到环境中其他应用的依赖指向,引发串扰(上图中应用B受到影响)。

PS:有被问及为何不调整被测应用的代码或者配置指向目标Mock,避免串扰其他应用。这种入侵代码的手段是下策。常在河边走哪有不湿鞋,总会有忘记改回来造成生产事件的时候的。

2)生效延迟

Mock的生效依赖注册中心的服务注册生效过程。由于缓存的存在,实际的生效时间是无法确定的,存在几秒到几分钟的延时。

对于功能测试场景而言,这些延时并无大碍,而在接口自动化测试场景中,这些延时将导致结果的不稳定性激增。为了避免延时带来的不确定性,通常会在测试框架中添加隐式等待的机制,重试调用被测接口,直到期望结果的出现,或者在达到最大等待时间后抛出异常。这么做的代价是测试执行效率的牺牲。在case数量很大时,这累计起来的等待时间就让人有些痛苦了。

现在问题比较清楚了,由于Mock的生效过程依赖服务架构中的“注册中心”,所以导致了Mock的串扰和延迟的出现。看着不是大问题,但确实用着不舒服。抽象一点说就是,“测试的过程依赖了被测系统的一个基础组件,造成测试执行稳定性的下降”。

三、解决思路

1)Mock 边车化,为应用提供本地化的Mock,使Mock同具体服务架构解耦。Mock一对一服务被测应用,以隔绝多应用间串扰的可能。

2)Mock 的启用和断开,通过控制被测应用所在JVM代理相关系统变量进行。即Mock的存在对应用透明,不依赖服务架构也不侵入应用代码和配置。

下图展示了应用与Mock的概要部署关系:

解决方案概述

上述问题的解决方案由四部分组成——servlet agent、本地 Mock代理、Mock server、Mock 配置客户端。

  1. servlet agent(开关):设置被测应用所在JVM的网络代理相关系统变量,导出应用对外请求,转发至“本地 Mock代理”。同时提供API供“Mock配置客户端”调用,以供人员或者脚本控制Mock的链接可断开。就是被测应用Mock与否的热开关。如图:
  1. 本地 Mock代理(桥梁):根据自身维护的路由配置转发请求至Mock server或者原始目标服务器。同时提供API供“Mock配置客户端”进行路由表的配置。在Mock启用的状态下,作为被测应用到Mock服务或者真实依赖之间桥梁。如图:
  1. Mock server:就是原本意义上的Mock。根据Mock的配置内容进行具体response的返回。市面上也有不少开源的Mock工具可以放在这块来用,最好选择提供了API供外部调用进行设置的。这样跟“Mock 配置客户端”对接起来工作量就很小了,在方案中的位置如上图。
  2. Mock 配置客户端:提供简单的API,在方案中的问题如上图。
  • 供测试脚本调用,在测试脚本中直接控制Mock的链接,断开,启动,停止,和具体Mock的设置。
  • 供GUI工具调用,让测试人员可以控制Mock行为。

最终对测试脚本暴露出来就是这个“Mock配置客户端”吐出的具体API。这部分可以发挥想象力,结合具体场景包装的使用起来方便些就行了。

Mock的开关和配置过程简图:

Mock打开时的依赖请求过程简图:

四、小结

我们通过使Mock本地化,给Mock加开关(servlet agent),做桥梁(本地Mock代理)的方法解开了Mock工具同服务架构之间的耦合关系,解决了启用Mock时的串扰和延时问题。

我们发现这个方案存在一定的普适性,未来可以考虑把Mock开关从 JVM层(servlet agent)下降到系统层,那么也就具备了服务其他语言应用的能力了。

作者介绍

Peter Sun,携程高级测试经理。

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/WMYsVdFtBZUO4YzogB9H
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券