开源测试工具 App 接口测试工具之 apimock (支持 anyproxy)

zhangzhao_lenovo · 2016年11月16日 · 最后由 zhangzhao_lenovo 回复于 2016年11月28日 · 2390 次阅读

作为续篇,随大趋势也弄了弄 anyproxy,但一路下来觉得坑也是蛮多的。


简介


apimock 是一款轻量化接口返回 mock 工具,用来测试 app 对服务端返回的容错能力。

具体请看前篇 :

App 接口测试工具之 apimock (动态 mock 服务器返回)


anyproxy

anyproxy 实际与 fiddler 完成的事情是一样的

自定义一个 rule

module.exports = {
    shouldInterceptHttpsReq :function(req){
         return true;     //劫持https
    },

    replaceServerResDataAsync: function(req,res,serverResData,callback){
        if(req.headers.host == host && res.statusCode == "200"){
            var charset = 'utf-8', charsetMatches = res.headers['content-type'].match(/;\s*charset=(.+)/i);
            if(charsetMatches){charset = charsetMatches[1];}
            var body = iconv.decode(serverResData,charset);     //根据编码提取出response
            var jquery = body.match(/jQuery(.*)/i);
        if (jquery) {var rawbody = body.match(/(\{.*\})/g);       //对https返回的jquery做修正为json,这个jquery之前没接触过,不是很确定做法是否对!
            }else{var rawbody = body;}
            var mockbody = '';
            try{
                var j = JSON.parse(rawbody);
                if (typeof(j) == "object" && Object.prototype.toString.call(j).toLowerCase() == "[object object]" && !j.length) {
                    var api = url.parse(req.url).pathname;
                    rawbody = api + ':' + rawbody;
                    var client = new net.Socket();
                    client.connect(port, server,function() {     //与mockserver通信
                        client.write(rawbody);
                    });
                    client.on('data',function (buf) {   //回调接收mock后的data
                        mockbody = buf.toString();
                        client.destroy();
                    });
                    client.on('close', function() {
                        rawbody = mockbody;
                        try{
                            var j = JSON.parse(mockbody);
                            if (typeof(j) == "object" && Object.prototype.toString.call(j).toLowerCase() == "[object object]" && !j.length) {
                                if (j['mock']['responsecode'] == '200') {
                                    delete j['mock'];
                                }
                                ...
                        }catch(err){
                        }finally{
                            rawbody = iconv.encode(rawbody, charset);
                            callback(rawbody);       //将mockbody返回
                        }

案例

案例 1 : 修改一个 https 接口返回,将值 errno=0 修改为 errno=10

启动 anyproxy,启动 mockserver,尚未定义 mock 命令,所以能看到截获的原文

执行 proxy.py xxxapi -k errno=10,mockserver 动态修改了内部 mock 规则

再次访问 api 发包,从 anyproxy 看到已经将 errno 修改为=10 了

案例 2 : 修改一个 api 返回为空 json

效果很明显,触发了一个必现的崩溃


遇到的问题

1.nodejs 的回调式带来实现上的缺陷

可能对 nodejs 理解的还不是很透彻,按 anyproxy 官网上的案例可修改返回的 responsed code,需要实现 replaceResponseStatusCode: 这个回调,但已经在 replaceServerResDataAsync 中实现了与 mockserver 的通信,而且两者不是串行关系,被 mock 的 responsed code 尚不知如何应用到 replaceResponseStatusCode 中,此处待研究

2.手机用 anyproxy 代理后不能上网

自己的 win7 64 启动 anyproxy 代理,手机端也配置好连接该机 wifi 和该 anyproxy 代理端口,却不能访问网络,anyproxy 中也没有该手机相关的任何数据包。手机上去掉 anyproxy 代理端口就正常了。同样配置改为使用 fiddler 可正常抓包。尚不清楚此原因

查看 anyproxy 的 issue,确实也有人提过类似问题。https://github.com/alibaba/anyproxy/issues/76

以上 2 个问题在 fiddler 中均不存在

开源地址

https://github.com/zhangzhao4444/Apimock

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

我也用这个方法给自己的 app 测试下

#1 楼 @zasdsd 赞,有问题或者需要改进的联系我。

测试小白一枚 之前用 fiddler+jmeter 做 APP 客户端的接口测试 请问怎么测 APP 服务端的接口?

#3 楼 @Minoz_wqd 服务端接口 可以参考https://testerhome.com/topics/6256 中的 fuzz 。但如果是刚接触服务端接口测试还是建议按传统方式。

估计是 https 的问题吧. 可以用 fiddler 做个中转看看.

#5 楼 @seveniruby 恩,还真不是 https,这个问题回头静下来再好好研究看看。

记得更新自己的打赏二维码. 有同学想打赏.

关于 responsed code 的修改是可以的,只是楼主你的 anyproxyjs.js 里面的这句写错了

code = Int(j['mock']['responsecode']);

应该为:

code = parseInt(j['mock']['responsecode']);

这样改正以后就没问题了。

需要 登录 後方可回應,如果你還沒有帳號按這裡 注册