通用技术 Mock Better 测试策略的改变和实践

扫地僧 · 2016年10月17日 · 最后由 周冬彬 回复于 2016年12月02日 · 5837 次阅读

敏捷模式中如何提高自动化测试效率

传统的做法,UI 自动化、接口测试、性能测试、健壮性测试.....等各种测试分而治之、测试结果也没有建立起内在关联性。B2C 产品的快速迭代,留给测试的时间不多,如何在自动化层面提升执行效率、提高定位问题效率一直存在痛点。
我一直在想,如何分层并行、多类型测试并行、不同类型的测试结果建立内在联系,这至少是解决以上痛点的一个可行性方案。
AutoTraveler 探索性遍历的实现,让我突然有了灵感,可以让一个驱动引擎把各个独立的 UI 测试、接口测试、数据层测试、稳定性测试、健壮性测试、前端性能测试、问题分析定位等串联起来,一次执行多种测试,形成测试闭环,测试结果以时间轴为纽带,建立上下文联系,这是个可以去探索实践的解决方案。
经过一段时间的折腾,已初步把 UI 测试、稳定性测试、前端性能测试串了起来,也做了一个 Report Center 提供公共 api,但这不足以形成前后端测试的一个闭环。通过多方调研,发现了 anyProxy 这个工具,可别小瞧它,有了它,再给它赋上一些测试的属性,就可以打通前后端的任督二脉了,下面是关于 Mock Better 的介绍。

Mock Better 设计需求

总体目标

  • 界面友好性,操作傻瓜化,为各业务组的实施落地降低技术门槛
  • 为 AutoTraveler、UI 自动化等驱动引擎提供健壮性测试、接口测试、后端问题定位的功能

实现功能

  • 按排队处理机制使用 anyproxy 服务,系统会实时播放 anyproxy 的使用情况(已实现)
  • http、https 报文录制持久化功能(已实现)
  • 报文篡改规则的创建和维护功能,模拟后端数据(验证前端功能,已实现)
  • 接口、未渲染页面的断言管理和并行测试功能(验证后端数据,开发中)
  • 后端返回报文异常,调用后端资源定位问题(定位后端问题,开发中)

Mock Better 实现原理

Mock Better 是基于 anyproxy 做的,首先了解下 anyproxy 可以做什么,借用官网的图很直观。

anyproxy 通过代理实现中间人劫持的目的,说形象点就是前后端之间的交互被监听了,甚至可以控制了。既然拿到数据了,它提供的接口就可以实现篡改 Request、伪造 Response、篡改 Response 等功能。

Mock Better 要做什么

1.编写 rule file 带技术费体力,更不要说管理和维护成本了。Mock Better 通过界面化、傻瓜化操作,创建和维护篡改规则,提升工作效率;
2.增加断言、测试集等测试属性,并通过一系列手段打通前后端测试的关联性,举几个例子发散下思维:
前端测试场景一:用常规手段造数据(后端传过来作用于前端)以达到边界值、等价划分类的场景代价很大,通过篡改接口返回的数据,就能很轻松的达到目的;
后端测试场景二:如果前端做了校验和屏蔽(前端传过去作用于后端),要校验后端服务或接口对边界值、等价划分类的的处理,通过篡改请求参数,也能达到目的;
后端测试场景三:如果通过断言发现报文异常,通过关键字调用后端的日志查询接口,定位错误上下文;
数据测试场景四:配置 DML 模板,以请求的参数作为查询条件获取预期结果,以响应的关键内容作为实际结果,进行数据层的校验(待实践探索阶段);
安全测试场景五:通过伪造请求头信息,篡改请求参数,校验后端的防守指数等。

以上,Mock Better 只是整个方案的一个重要组成部分,要真正达到目的,还需要驱动引擎(形式不限,如 AutoTraveler、UI Auto Test Framework 等)、测试结果处理引擎、统一报告平台等。

Mock Better 中的后端测试和传统的接口测试的区别是什么

首先,传统的接口测试其重要性是不可替代的,我把它定义为属于前置阶段的,通过 Mock Client 实现的接口测试,特别是接口场景化测试可能需要解决模拟登陆态、自定义头信息、重定向控制、代理、加签、HTTPS、关联参数绑定、前端动态参数生成等问题。我相信包括我自己,很多人的接口测试框架已攻克了这些问题。
Mock Better 中的后端测试的区别在于以下几点:
1.不仅限于接口,还包括未渲染的页面;
2.相对于传统的接口测试,介入的时间节点更往后,和 UI 测试是并行的;
3.最大的区别在于它是探索性遍历、UI 自动化等引擎驱动的,所以模拟登陆态、关联参数绑定等不是它处理的,它是在端到端的交互过程中,通过配置的规则,动态命中完成测试的。说通俗点,传统接口测试要解决的问题,引擎都帮你做了;
4.相对于传统的接口测试,其寄生于真实环境之中,更贴近真实场景。

Mock Better 功能介绍

1. 获取证书
手机用户可直接扫描二维码,PC 用户下载后安装

2. 报文管理

点击 “开始录制”,后台会自动生成用于录制的规则文件,并启动 anyproxy 应用 rule file

var mysql      = require('mysql');
var _host      = 'localhost';
var _port      = '3306';
var _user      = 'root';
var _password  = 'root';
var _database  = 'qmock';

module.exports = {
    replaceServerResDataAsync: function(req,res,serverResData,callback){
        var col;
        var connection = mysql.createConnection({
            host     : _host,
            port     : _port,
            user     : _user,
            password : _password,
            database : _database
        });

        connection.connect();

        try {

            if(null != serverResData ) {
                serverResData = serverResData.toString();
                var tempJson = serverResData;
                tempJson = JSON.parse(tempJson);
                col = null != tempJson ? tempJson.type : "";
            } else {
                col = "";
            }

            var insertSQL = 'insert into response(uuid,host,url,col,method,contentType,userAgent,email,tag,response) values(replace(uuid(), "-", ""),"' + req.headers.host + '","' + req.url + '","' + col + '","' + req.method + '","' + req.headers['content-type'] + '","' + req.headers['user-agent'] + '","quqing@com.cn","1",' + JSON.stringify(serverResData) + ')';
            console.log("insertSQL -> " + insertSQL);

            connection.query(insertSQL, function (err, res) {
                if (err) console.log(err);
                console.log("INSERT Return ==> ");
                console.log(res);
            });



        } catch(err) {
            console.log(err);
        } finally {
            callback(serverResData);
            connection.end();
        }
    }
};

同一台服务器,录制功能启用后,其他人进入排队等候,完成录制后的报文列表,用户可以有针对性的创建篡改规则

3. 报文详情
显示报文的主特征信息,用户可以选择做篡改,也可以选择做断言

4. 创建篡改规则
这里是规则集的概念,一个规则集可以包含多个规则项,step by step 向导方式引导用户创建


启用规则,会根据配置自动生成用于篡改的规则文件,并启动 anyproxy 应用 rule file

module.exports = {
        replaceServerResDataAsync: function(req,res,serverResData,callback){
        try {
            if(null != serverResData ) {
                serverResData = serverResData.toString();
            }
                        if( serverResData.indexOf("xxx") != -1 && req.headers.host.indexOf("xxx") != -1 && req.url.indexOf("xxx") != -1 && serverResData.indexOf("xxx") != -1 ) {
                serverResData = serverResData.replace(/"xxx":".+?"/g, "\"xxx\": \"999\"");
                console.log("update -> " + serverResData);
            }

        } catch(err) {
            console.log(err);
        } finally {
            callback(serverResData);
        }
    }
};

5. 规则列表
用户可以修改、删除、启用篡改规则。为避免规则集相互之间的干扰和冲突,一次只能启用一个规则集

6. 修改规则
规则集包含多个篡改规则项

6. 更新规则项
为了适应接口可能发生的设计改变,提供了更小粒度的规则项修改,支持参数类型和篡改值的更新

测试没有终点

向所有默默无闻的实践者致敬

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 51 条回复 时间 点赞

和我们团队开发的一个 mock 平台类似,楼主是打算把 UI 自动化,接口自动化,单测自动化的任务和结果全部收纳到你这个 web 系统里面是嘛?

#1 楼 @simple 这个系统只是整个解决方案的一个组成部分,主要目的是打通前后端的联系

#2 楼 @quqing 楼主前端写的不错 👍
BTW: 如果支持接口字段编辑的话,可能会面临业务逻辑上的 challenge,比如字段要取随机数怎么办?字段关联怎么办?字段加密怎么办?接口有执行顺序怎么办?接口执行以后需要检查有没有触发第二个接口的执行,等等诸如此类的内容

#3 楼 @simple 传统的前置型接口测试确实要解决参数动态绑定和场景化的问题,之前写了个接口测试的框架,可以查找我之前的帖子。
这部分的接口测试和 UI 测试是同步的,这一切都是跟着 ui 场景化测试或者探索性遍历测试一起进行的,所以基本不存在你说的问题

#4 楼 @quqing 明白了,类似一个行为监控和记录的系统,又有点像录制行为的?

#5 楼 @simple 差不多就是这个意思,只不过在中间人劫持的基础上做了一些规则的命中处理

如何录制这些流程貌似都没写. 与 anyproxy 如何结合的? 不少人估计没看懂

anyproxy 成了很多测试工具的胶水和路由了

#4 楼 @quqing《比如字段要取随机数怎么办?字段关联怎么办?字段加密怎么办?接口有执行顺序怎么办?接口执行以后需要检查有没有触发第二个接口的执行,等等诸如此类的内容》这部分没太明白为什么没有这些问题了。 同样如果接口参数个数就改变了怎么办,接口依赖很复杂的数据怎么办,各接口之间依赖的数据有冲突怎么办,各接口依赖过强过长其中一个接口 bug 了导致大部分 case 都失败了怎么办,断言的报文是随机生成的怎么办,断言报文不够还需要断言数据库怎么办,断言数据库也不够需要断言各种 hadoop 集群和文件系统怎么办,功能是异步执行必须等一个执行成功的状态怎么办,已经铺开了大规模自动化测试,但是突然接口,UI 等都发生了变化怎么办。等等等等,感觉要考虑的情况很多

#10 楼 @ycwdaaaa 你说的接口测试是 mock client 的模式,这个早有解决方案,我说的是自动化引擎驱动的接口测试。例如:自动遍历同时也可以验证接口,实现模式不一样的

#11 楼 @quqing 模式不一样也回避不了一些问题的

#12 楼 @ycwdaaaa 可能文章关于原理写的不清晰,有空再详细说明

#8 楼 @seveniruby 嗯,有时间把实现原理补充下

#12 楼 @ycwdaaaa 已增加原理描述,和传统接口测试区别

#15 楼 @quqing 我理解篡改 response 就是 mock server,伪造 request 就是接口测试。我没太看明白有什么本质的不同,为什么不会遇到那些问题,难道 request 和 server 同事全 mock 了? 能再说详细点么

#16 楼 @ycwdaaaa 这里所说的接口测试由驱动引擎发起,不需要伪造 request,也不需要 mock response,一切基于规则命中触发校验。
你设想一下,引擎触发起端到端的测试(这个文中也做了说明),代理又监控到了前后端之间交互所有的数据包,程序要做的就是通过规则命中要测试的接口,并根据断言校验是否异常,所以不会遇到传统接口测试的那些问题。

#17 楼 @quqing 能举个例子么?

#18 楼 @ycwdaaaa App 测试为例:Mock Better 设置好规则,启用规则,手机连上代理,由引擎发起 App 测试,此时所有操作产生的数据流都在监控之中,Mock Better 会在这些来来往往的数据流中根据规则命中匹配到的接口执行测试。

#19 楼 @quqing 你没有说你再测什么啊? 规则都是什么规则? 能举个例子么?

#19 楼 @quqing 我理解你用自动遍历的方式,随机频繁的点击 UI 上的控件来做驱动测试对么? 然后监控 http 的 request 和 response。 那你说的规则都是什么? 篡改 response 和 request? 断言的也是 response?

#21 楼 @ycwdaaaa 也不一定是自动遍历,先用心看一遍文章吧

#22 楼 @quqing 我已经很用心看了,真心没看明白这个工具能解决的测试点在哪

#21 楼 @ycwdaaaa 文章中有篡改规则,断言规则类似

#24 楼 @quqing 能举个实际的例子么

#25 楼 @ycwdaaaa 已经说的这么清楚了。。。难不成请你到公司来当你的面演示一遍😀

#26 楼 @quqing 真没觉得你说的很清楚,通篇文章都是高大上的专有名词,但就是没写解决什么问题了,问你你也不说。。。。真的,这文档除了你谁也看不明白

#27 楼 @ycwdaaaa 自然有都看得懂的

#26 楼 @quqing 我这么说一遍吧,看看我理解的对不对。这个工具的目的是通过自动遍历的方式(假设就以自动遍历为例子),自动的频繁的点击 UI 上的控件。触发接口调用,你的工具在监听 app 的 request 和 response。你可以截获这些报文做修改,假如特意让 response 里返回特别大的数来 check UI 做边界值测试,也可以修改 request 传入特别大的值。这样你来做接口测试和 UI 测试对么? 不知道我这么理解对不对

#29 楼 @ycwdaaaa 不对,文中有写的,我再补一刀吧
前端测试场景一:用常规手段造数据(后端传过来作用于前端)以达到边界值、等价划分类的场景代价很大,通过篡改接口返回的数据,就能很轻松的达到目的;这个是需要篡改 response 的。
后端测试场景二:如果前端做了校验和屏蔽(前端传过去作用于后端),要校验后端服务或接口对边界值、等价划分类的的处理,通过篡改请求参数,也能达到目的;这是需要伪造 request 的。
后端测试场景三:如果通过断言发现报文异常,通过关键字调用后端的日志查询接口,定位错误上下文;这即不需要伪造 request 也不需要篡改 response,设置断言后劫持实现。
数据测试场景四:配置 DML 模板,以请求的参数作为查询条件获取预期结果,以响应的关键内容作为实际结果,进行数据层的校验(待实践探索阶段);即不需要伪造 request 也不需要篡改 response,劫持实现。
安全测试场景五:通过伪造请求头信息,篡改请求参数,校验后端的防守指数等。需要伪造 request 的。

#30 楼 @quqing 这个跟我理解的有什么区别么? 不是修改 request 和 response 么?

#31 楼 @ycwdaaaa 当然有区别,你怎么都不仔细看,做测试的首先要学会静下心来

#32 楼 @quqing 我真的是仔细仔细再仔细的看了。一共就这么几句话。 但是这几句话里充斥着各种高大上的名词,就是没说到底解决了什么问题了

后端测试场景三:如果通过断言发现报文异常,通过关键字调用后端的日志查询接口,定位错误上下文;这即不需要伪造 request 也不需要篡改 response,设置断言后劫持实现。
数据测试场景四:配置 DML 模板,以请求的参数作为查询条件获取预期结果,以响应的关键内容作为实际结果,进行数据层的校验(待实践探索阶段);即不需要伪造 request 也不需要篡改 response,劫持实现。
请仔细看,这两条需要修改 request 和 response 吗?

#34 楼 @quqing 后端测试场景 2

这个不是在该 request?

#34 楼 @quqing 我一开始说的,猜测你的原理就是修改 request 和 response 啊? 无非就是再加个断言和查询日志。我这说的也没错啊

#36 楼 @ycwdaaaa 修改和劫持的目的不一样,应用场景区别大了,做为测试,不应该有严谨的态度学习吗

#37 楼 @quqing 那你继续玩你的文字游戏吧。一开始吹上天了能解决 UI 测试、接口测试、数据层测试、稳定性测试、健壮性测试、前端性能测试、问题分析定位这些问题。结果就是在自动遍历上加个报文修改和验证,哦对了,按你说的应该是劫持。是我土鳖了,是我不会玩高大上的文字游戏。 但这个工具依旧没什么卵用,根本解决不了文章一开始说的那些问题。哎,作为测试,难道不该有踏踏实实做事,不吹牛逼的性情么?

#38 楼 @ycwdaaaa 在公司已经落地了的解决方案,你凭什么说在吹,已耐心给你解释多遍,做人没有感恩的心也罢了,恶意攻击就是人品问题了

#39 楼 @quqing 如果你觉得你这是在耐心的解释那我也是无语了,从刚一开始我就问你应用场景是什么,建议举个例子。 你就支支吾吾说直接看文章。问你那么多问题,你跟我拽各种文字游戏。最后拽到修改和劫持的问题了都。 质问我测试不应该有严谨的态度么?然后说我恶意攻击。 我真是醉了。 以后我也可以发个文章说我已经实现所有场景的测试人工智能化了。但我不告诉你们应用场景,反正我实现了,我再公司已经落地实践了

楼主调调起的有点高,然后讲故事不落地,导致误会了,尽量场景化通俗易懂,授人以渔是好事,但是别总技术大牛自居,反效果了;aaaa 兄弟太过认真了,都洗洗睡吧;😂 😂

#41 楼 @skyofdl 恩,不吵了,洗洗睡

#41 楼 @skyofdl 我相信有看得懂的人,但不能保证人人都看得懂

楼主和 aaa 兄弟别吵了,我认真看了,确实能做到 mock server(修改 response),以及 mock client(修改 request),这两端的边界值判断,等价类划分的健壮性我相信确实能得到检验。但我也被楼主列举的『后端测试场景三』和『数据测试场景四』中所描述的弄晕了。本来把自己的技术及落地 share ,目的就是让别人在思想上有参照,甚至能找到自己日常碰到的技术瓶颈的解决方法,如果用『但不能保证人人都看得懂』,这个攻击性就很强了,而且离分享的初衷也远了,其实有很多点楼主可以细说说:

  1. anyproxy 的胶水作用
  2. 如果动态的添加规则,那 anyproxy 的 rule_file 那一块不具备更新功能,服务需要重启吗?
  3. 健壮性测试,对于 level 不同的测试人员,针对不同的接口,哪种类型的字段更适合为它设置规则?
  4. 断言的设置,真正涉及到接口依赖很多,外部服务冗杂的时候,如何做?
  5. ... 希望能有更接地气的解释

#44 楼 @fenfenzhong
关于 1、2,底层还是调用脚本控制 anyproxy 服务的停止、重启及应用 rule file,至于是如何管理和触发的,通过监控 anyproxy 的进程,配合数据库记录的标记位,实现排队处理逻辑。控制入口就是页面上的 “开始录制”、“停止服务”、“启用规则”、“停止规则”。
关于第 3 点,目前是在配置向导,有报文提供参考,一个规则集下可以包含多个规则项,至于篡改哪个字段,篡改值设为多少,由使用者根据测试需求设置,这里说明下,启用了某个规则集,使用完毕停止后才能启用其他规则集,这些在系统消息里面会有提示的。
关于第 4 点,我觉得前面已经尽力解释了和传统接口测试的不同,基于 UI 触发的端到端场景测试,由界面触发的接口调用一直真实存在吧,只是以前看不到摸不着,这些接口的发起不是 mock client 发起的,而是真实的场景调用,所以不需要考虑依赖关系等许多问题,我们要做的只是根据规则命中它,然后和预设的断言比较是否有问题,如果有问题,我们还可以根据接口关键字调用后台日志查询接口过滤到错误的上下文。
我也郁闷了,第 4 点该怎么解释了。。。

#44 楼 @fenfenzhong 我跟他吵吵的原因更多在于这篇文章明显是以装逼为目的而不是分享为目的,这个目的性很重要。以分享为目的的文章会很落地,从应用场景,解决的问题,相关配置说明不说很详细但也会很清楚。而不是在文章一开始就高调声称此工具很牛逼,非常牛逼,解决了各种各样的问题,列出一堆高大上的让人懵逼的专业名词却连最基本的应用场景都没有解释清楚,好像生怕别人知道一样。但别人究其细节发现不过是现有工具上包了一层而已,根本没有在文中宣称的一样解决了那么多种测试类型的问题。而且对于他人深问的问题一律不回答最后丢一下一句我不保证所有人都看得懂。 这样的分享有何意义? 通篇我只看到了两个字:装逼。 我觉得既然选择在社区做分享,就得对自己的文章负责任,很多的读者都花费了自己宝贵的时间去阅读去研究每一个对他们有用的文章,这是一个平台,而不是信口雌黄的地方。 如果社区里已经都是各类吹牛逼的水文,那我们还来这里做什么?

#46 楼 @ycwdaaaa 最后悔的是和你这种无知又狭隘的人交流,你是怎么想的就会把别人看成是怎么想的,不是每个人来这里分享的目的和你一样。

#47 楼 @quqing 你继续装逼,我只是看客

#48 楼 @ycwdaaaa 也只有你这种人,看不懂就会咬人,自负又自卑。

扫地僧 [该话题已被删除] 中提及了此贴 10月21日 13:28

看过我的文章的人应该清楚,我的风格基本上都是部分落地或完全落地后再分享的,正如文章开头已说明,这个解决方案虽然前端测试部分已经落地,但还有 2 个需求在进行中,最终接口的落地效果会再次分享,条件允许会开源,谢谢支持我的人,也谢谢那些能看懂这篇文章的同行

扫地僧 Mock Better 测试策略的改变和实践-续 中提及了此贴 12月02日 01:22

最近好像很多人都在用 anyproxy,我最近也在做类似的事情,所以想问几个问题哈~

  1. 除了 json 格式的报文以外 html/xml/image 类型的报文有做篡改等行为么?
  2. 楼主的后台界面看起来不错啊,是什么模板呀?我后台用的 node 服务器去 bootstrap 官网上找的一些控件,做起来总感觉好难看,有时候还有 BUG
  3. mock client 情况下是通过 UI 自动化等方式驱动的场景下录制的,然后再进行回放测试么?
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册