zoukankan      html  css  js  c++  java
  • 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请求(getpost)的测试工具,例如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测试平台,整体上将更利于测试效率的提升。

      

    免费体验云安全(易盾)内容安全、验证码等服务

    更多网易技术、产品、运营经验分享请点击



    相关文章:
    【推荐】 私有云爆发,未来增长空间巨大
    【推荐】 kubernetes大概的工作原理
    【推荐】 如何实现最佳的跨平台游戏体验呢?

  • 相关阅读:
    JQuery
    如何垂直居中一个浮动元素
    Bootstrap概述
    浮动元素的水平居中
    图(Prime算法、 Kruskal算法、Dijkstra算法、Floyd算法、AOV网)
    排序(插入排序、选择排序、交换排序、二路归并排序、基数排序、外部排序)
    实验二 Scala编程初级实践
    数据类型、运算符
    用栈求前缀表达式值
    用栈求后缀表达式地的值
  • 原文地址:https://www.cnblogs.com/163yun/p/9887693.html
Copyright © 2011-2022 走看看