内容简介:此文已由作者翟曜授权网易云社区发布。欢迎访问网易云社区,了解更多网易技术产品运营经验。mock测试常见的定义为:在测试过程中,对于某些不易构造或不易获取的对象,通过创建虚拟对象的方式来模拟测试的测试方法。
此文已由作者翟曜授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
mock测试常见的定义为:在测试过程中,对于某些不易构造或不易获取的对象,通过创建虚拟对象的方式来模拟测试的测试方法。
提到mock测试工具,java领域内可能首先想到的是Jmock、EasyMock、JMockit等。通常在单元测试中,由于对象、方法不是独立的,测试代码难以构造,所以业界提出了Mock Object技术来孤立被测试的对象。以上几种Mock 框架都限于一个Mock概念:即Mock Object 是用来代替与代码协作的对象的对象。和这几种框架一样,其他的 mock 框架也基本都局限于单元测试范畴,而在集成测试功能测试阶段还没有相应成熟的框架进行支持。所以本文提到的mock测试,更确切来说,是在功能测试阶段解决如何与外部系统间的数据交互。
文章结合本人所在的项目【秀品】来做相关介绍。大多用户直接接触到的只是秀品商城,但实际整个秀品业务系统的运转比较复杂,其中便涉及到和多个外部系统的对接及数据交互,比如仓储和物流都会和EMS、顺丰等有数据交互。而最近秀品开始涉及跨境业务,相应和电子口岸、境外的物流商等又会有数据交互。
当然,跟外部系统对接时系统间的联调测试必不可少,有些外部系统提供测试环境,有些甚至不提供。即便是提供测试环境的外部系统,一般也仅在开发联调阶段配合提供联调测试对接服务,一旦联调测试结束,也不再继续提供测试服务。那么,当这些外部系统的联调测试环境不可用时,我们就需模拟这些外部系统来和秀品系统进行数据交互,以便支持秀品完整业务测试流程的正常进行。针对这类mock测试需求,秀品QA做了几种实践,也是在实践中总结再改进的过程。
秀品系统采用的通信协议主要有:dubbo协议和http协议。和外部系统对接都是采用http协议,所以目前只需模拟外部系统对秀品系统的http请求回调功能。
以秀品和EMS(仓储物流商)的WMS(仓库管理系统)交互为例,EMS会提供一份标准对外接口文档给秀品。不同业务接口的调用形式和接口参数基本是一致的,仅通过参数值传递与业务相关的数据。约定如下图所示:
以其中一个WMS回传消息接口为例:【入库单收货确认回传接口】,其处理业务说明:WMS系统在入库单完成入库(上架)后,将对应入库信息回传给外部系统(即秀品)。EMS提供的文档说明如下图:
结合秀品系统实现,EMS的回调最终只需拼接成这样一个请求:
秀品某测试机Ip+http端口号+调用路径+servicename+appkey+content(xml格式)
其中:Ip+端口+调用路径+appkey 与测试环境配置相关,基本不随业务变化。
servicename+content(xml格式)和业务有关,频繁变化。
针对该【入库单收货确认回传接口】,则只需拼接并执行这样一个请求:
http://host:port/oms/wms/ems?service=WmsStockInConfirm&appkey=xxxxxx&content=< RequestReceiveInfo> xxxxxxxx</RequestReceiveInfo>
说明:content为上图中xml格式的数据集。
如何处理这类mock测试?
WAY1:寻找能发送http请求(get\post)的测试工具,例如fiddler、postman。
fiddler大家都比较熟悉,主要介绍下项目中使用的postman。Postman 是Chrome 扩展,提供功能强大的 Web API & HTTP 请求调试。它能够发送任何类型的HTTP 请求 (GET, HEAD, POST, PUT..),附带任何数量的参数+ headers。其具备两个主要优点:
1.能够保留历史请求,这样我们就可以很容易地重新发送请求;
2.有一个“集合(collection)”功能,用于存储所有请求相同的API/域。
使用效果如图:
Postman其实已足以满足大部分同类测试需求,且使用成本不高,不需额外编写测试代码。但结合我们项目特点,这些mock会影响每一次订单流程扭转的测试,使用频率非常高,且存在许多需要mock的回调接口。所以,针对这些影响可得出以下可改进点:
1.数据主要集中在xml中,每次执行需根据不同测试数据更改xml,改起来费时费力且易出错。
2.虽有“集合”功能,但一个人的测试集也不便于及时共享给其他同学。
3.操作界面虽有b格,但过于简陋,真心不便。
综合postman的优缺点,不如尝试把测试集固化到 java 代码里,因此开始了尝试WAY2:利用java代码,基于httpclient发送请求。类似于http接口测试,测试集代码如下图:
说明:
分别构造出请求url,xmlinfo及所需各参数后,执行请求即可。针对xml的处理,每次执行只需参照代码注释更改相应框内的属性值即可,减少编辑时间和出错概率,且一人写的代码其他同学都可以共用,总体还是提高了测试效率,基本满足了测试需求,但仍存有可改进点:
1.执行时要基于IDE,需要更改xml文件中相应属性值,同时必须具备代码运行环境。
2.没有可视化操作界面,存在使用门槛,操作不够方便。
如果传参更为简单,使用者无需接触测试代码,不用基于本地运行环境且能够可视化执行,这样可进一步提升测试效率,于是开始了尝试WAY3:模板语言在mock测试中的应用,并结合jenkisn实现用户界面。最便捷的方式首先想到了结合jenkins,通过运行jekins job,只需在可视化的界面里传入参数值,便可“一键执行”成功模拟出接口的回调,很好地解决待改进的问题。
针对该解决方案:
首先,测试代码需上传服务器,需解决服务器上构建打包的规范问题,以便可以通过命令行传入参数调用到不同测试类及模板文件。
其次,针对xml文件作为请求参数,考虑引入FreeMarker模板引擎,基于模板生成xml文件输出。提取出xml中在实际测试场景中需频繁更新的属性,重新定义成一个Java do类,向匹配的ftl文件传值。从而整体简化测试代码的繁锁度。
另外,从 工具 使用角度考虑,传参过多,也会较繁锁,所以考虑将输入的参数合并为长字符串,传递到程序后再做拆分处理。
总之,在设计代码结构及编写程序时,秉承着一个原则:尽可能通用化。
结合最终需拼接并执行的请求形式:
Ip+端口+调用路径+servicename+appkey+content(xml);
其中Ip+端口+调用路径+appkey 与测试环境配置相关,基本不变;
servicename+content(xml)和业务有关,频繁变化。
做了如下改进:
1.将请求url中环境配置相关的共通部分抽取,定义为CommonURLDo,以便可以灵活运行在不同的测试环境。
2.将不同业务接口(servicename)对应的xml定义为不同的ftl模板文件。并将模板需频繁变化的变量提取,定义成业务DO类,建立DO和ftl的映射,通过DO向ftl传参。
3.为测试类更通用,将ServiceName参数化,通过传入的ServiceName,渲染出相应的ftl模板文件。一个测试主类便可支持所有同类的需求。
4.最后,针对一个业务场景,配置相应jenkins job,传入三部分必需的参数:【测试类名】+【与环境配置相关的通用信息】+【xml文件需频繁变化的属性值】,执行job,便可完成一次回调模拟。
如图,代码结构组织及大体实现如下:
首先,定义ftl模板文件及相应DO。
其次,执行测试主类main方法,参数依赖于jenkins job执行传入,执行主要分为3个steps:
其中,step2中根据不同servicename调用不同业务处理类,实现如下:
最终,jenkins job的使用者界面如下:
借助于jenkins的用户界面,成功实现了“一键执行”。
那么,来运行一个mock测试试试吧~
至此,一个完整的mock测试场景已成功完成。
在自己编写和使用工具过程中,也会不断总结出一些待优化点,根据项目后续实际需要再做扩展。当然,现在这种方式仍有其局限性:
1.如果可以更通用,实现通用的mock server,client端使用时不需添加测试代码且有操作页面,只需在页面上进行简单配置便可成功执行测试;
2.能够以产品/项目维度对场景用例进行维护,共享并存储一份测试case,维护管理更便捷;
3.能够提供对多种协议的支持,例如http、dubbo、hessian等;
4.对自动化测试和性能测试的支持,提供自动化的API调用,甚至可以对一些压力测试场景提供支持。
如果可以实现一个通用mock测试平台,整体上将更利于测试效率的提升。
更多网易技术、产品、运营经验分享请点击。
相关文章:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 宜信安全数据平台实践:OpenSOC改进之路
- 字节跳动在 RocksDB 存储引擎上的改进实践
- FreeBSD 13.0-RC1 发布:改进 TCP 性能、修复和改进 SCTP
- Lanai-UI 改进后发布,AdminLTE 改进后的脚手架
- 敏捷开发的持续改进
- Android 功耗改进
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。