作者简介
Chris Xia,携程资深前端开发工程师,关注前端技术更新和研发效率提升。
前言
本文描述的是2020年携程IBU机票研发团队基于业务痛点所研发的轻量级前端Mock解决方案(目前正与集团另一Mock中台融合,从中台的赋能中探寻更多拓展)。希望可以借此文为有类似前端Mock需求,正在寻找解决方案的团队/个人提供一种思路。
一、背景
在实际开发场景中,有很多前端需求是需要和后端基于契约进行并行开发的。因此不论是开发阶段,如何让开发和测试更简便地覆盖业务场景,提升开发质量,还是在产品验收阶段,如何在出现问题时精确、快速的定位,都是前端开发需要解决的痛点。
因此,拥有一个稳定、灵活、易用的数据Mock平台是保证前端开发和排查问题效率的重要前提。
总结前端在开发、调试、验收等各阶段需要Mock平台具备的能力后,我们整理出了Mock平台需要具备的核心功能:
1)实时请求数据可视化(抓包);
2)简单易用的Mock报文管理,支持设备维度的个性化Mock;
3)满足设备多接口不同环境的支持(复杂业务下不同接口不同团队开发,发布在不同环境的测试服务器上);
4)模拟延时,支持前端模拟不同业务场景下的展现;
在明确了主要需求后,我们开始调研公司内已有的和市面上主流的Mock工具和平台。
二、调研
公司内:
公司内已有一个功能集成较高的Mock效率平台,但是其主要的功能设计为面向服务端和测试,对上述单个设备维度及多测试环境的前端Mock需求支持度不够高。
市场调研:
外部市场Mock工具大致分为以下三类:
1)数据本地管理
该方法是将Mock数据存储在本地-代码或本地存储中,前端在业务代码中使用假数据或通过配置读取数据。这种做法会导致测试代码与业务代码耦合,提交代码和发布前必须删除测试代码或修改配置,容易造成生产事故。即使结合运行环境控制还是存在维护效率低、成本高的问题。
2)Mock平台:如RapYApi
开源的一些企业级Mock平台,提供了接口文档管理,接口数据模拟,接口调试等功能。但这些平台都是围绕接口的契约文档为核心对数据进行mock和管理,对于已经接入过接口管理框架(如Swagger)的组织来说,会存在接口文档同步难的问题。对报文实时回显和多接口不同环境的配置功能支持也不足。
3)代理工具:如Charles、Fiddler
轻量级的客户端代理工具,能满足日常开发抓包和简单的Mock需求。缺点是配置繁琐,对Mock数据的管理能力弱,数据和报文也无法共享。
因此我们根据自身痛点开发了Mars系统 –基于代理模式的轻量级前端Mock平台。较好的解决了上述痛点,支持了业务发展,显著提升了前端开发效率。
三、设计实现
对前端Mock平台而言,不论是PC,H5还是App,每个设备的Mock需求都会不同。为了解决设备间的差异性,我们将Mars定义为基于设备维度的Mock平台。
摆在我们面前的有两类实现方案:
方案A:往公司的服务治理中心注册Mock地址,前端需要在现有的基础网络设施上配置Mock地址。这种方案侧重对后端环境的模拟,需要强依赖服务治理中心,前端不同设备在Mock时需要再针对单个设备进行特定配置,不够灵活。
方案B:通过代理请求的方式,客户端将所有请求发送到Mock平台,平台内部判断是走Mock还是走原请求。这种方案对请求的控制更加精细,同时也可以将客户端的配置工作转移到Mock平台上,客户端使用起来更加方便灵活。
综合考虑优缺点后,最终选择代理请求的方案B来实现Mars平台。
Mars的使命是让设备接入后,从请求发出到接收响应再到Mars回显数据,可以清楚的观测到接口信息和Mock命中情况,让前端的数据流由原本的黑盒变为白盒,使整个Mock流程形成一个闭环。
平台的设计中包括两个部分:
一是GUI层,负责数据展示和管理用户操作,主要分为实时报文展示,Mock数据管理以及环境配置等模块,如下图蓝框部分;
二是数据处理层负责处理设备的请求响应,主要分为设备参数解析,Mock数据筛选以及请求转发等模块,如下图红框部分。
图1 Mars框架图
四、功能实现
4.1 数据实时回显
在日常的开发调试中,经常需要查看页面元素对应的接口数据。我们将已发出的请求实时回显到Mars页面上,方便观察接口数据变化。
此功能基于Websocket实现。用户在Mars上选择设备进入设备详情之后,前端通过Websocket与平台建立通信链接,这时后端会保存一个以设备号为ID的Websocket链接实例,之后,平台将该设备的所有请求通过该实例回显到Mars前端页面上。
图2 Mars数据实时回显图
4.2 Mock数据控制
Mars除了支持接口配置固定Mock数据以外,还对其他复杂场景进行了支持,例如同一个接口,根据不同的请求参数返回不同的Mock数据,即接口与Mock数据之间可以分别实现一对一和一对多的关系。
此功能主要利用了Json报文数据格式化的特性。通过在平台上配置JsonPath脚本,让Mars对收到的代理请求进行解析,返回相匹配的Mock数据。
4.3 网络环境切换
这里的网络环境指的是业务接口的测试,堡垒,生产等环境。
当设备需要在指定的网络环境中测试某些功能时,正常情况下前端需要在代码中增加一些配置指向特定的网络环境。在接入Mars后,因为使用的代理模式,这些配置工作被转移到平台上,在平台上配置好需要的环境后,在平台上直接切换前端就生效了。
在实际应用过程中,我们还遇到了更复杂的业务场景。如后端有多个接口发布在不同的测试环境上:业务需要的接口1被发布到测试环境A,而其它接口在测试环境B。
这里,我们通过增加子环境的概念,将子环境与设备绑定,实现以接口为维度的环境控制且设备之间相互隔离。回到这个问题,就是针对测试设备在Mars中增加一个子测试环境A,并将设备的基础环境设置为B。Mars会将该设备发出的指定接口1转发至子测试环境A,其他请求转发至测试环境B。具体如下图所示
图3 Mars环境切换流程图
4.4 模拟延时
很容易理解,客户端请求被代理后,相当于是与Mock平台建立了连接,在平台上为响应设置延时,模拟真实请求返回时间。这样就可以帮助前端轻松构建网络卡顿、超时等各种情况下的表现了。
在上述核心功能被实现后,Mars基本满足了我们对Mock平台的核心诉求。Mars发布上线后,通过收集用户需求和反馈,我们基于核心功能对平台进行了拓展,使Mars兼容了更多复杂场景下的问题。主要举例以下两点
Mock数据集
上文提到的Mock数据控制,主要体现在对单个接口的Mock数据上,单接口Mock数据与设备绑定,主要适用于开发调试阶段对一些零散接口进行Mock调试。
而在集成测试阶段,一个业务场景通常涉及多个接口,不同业务场景下对同一个接口要求的返回数据也不同。如测试预订单程和往返下单流程,同样的查询和政策接口要求返回数据完全不一样,这种情况下操作单接口Mock数据费力度很高。
所以我们在单接口Mock的基础上拓展了Mock数据集的概念,将单个场景中多个接口的Mock数据打包成一个集合,设备直接使用集合,极大的提升了Mock数据管理效率。
后端Mock应用
后台服务间的相互调用,调用方实际上也相当于是前端,因此我们将这套代理模式的Mock方案也应用到了服务间的调用上,降低了后端对上游服务的依赖。同时,将Mock数据集功能与接口自动化测试相结合,为自动化测试平台提供数据支持,使服务端接口自动化测试覆盖率提升至90%以上。
五、一些问题
基于代理模式的Mock方案为实现实时报文显示和子环境切换功能提供了便利,但也引入了一些问题,如:
1)内存占用较大
代理模式下客户端的所有请求响应的数据大小对于Mock平台来说都是未知的,当遇到数据量大的接口被频繁调用时,会造成应用内存升高,JVM触发Full GC影响性能。需要在申请Mock应用内存时对使用量进行合理评估,保证稳定性。
2)响应时间增长
代理模式相当于多了一层网络调用,接口的响应耗时会有所增加,在需要测试接口极致性能时,需要评估代理方式是否适用。
六、结语
Mars平台目前已被多个团队使用,产出近2W条Mock数据,600多个Mock数据集,平均每天代理130个左右设备的流量,基本满足了在开发调试过程中95%的Mock需求。与此同时,我们也一直在使用过程中不断验证、优化,并开始与携程内部其他开发效率工具融合,使Mars能为IBU机票业务的快速发展保驾护航。