鳞状上皮内高度病变什么意思| 怔忡是什么意思| 风疹吃什么药好得快| 失聪是什么原因造成的| 放屁多吃什么药好| mu是什么单位| 枸杞与菊花一起泡水喝有什么功效| 玻璃体混浊用什么眼药水| 自食恶果是什么意思| 乳头痛什么原因| 两个夫一个车是什么字| 车万是什么意思| 梦女是什么意思| 什么原因得湿疹| 令瓦念什么| a股是什么意思| 李世民的字是什么| 成人感冒挂什么科| 甲亢是什么原因引起的| 皮蛋为什么含铅| 怕金森是什么症状| 舌苔发白是什么原因| 阴疽是什么病| 老人脚肿是什么原因引起的| basic是什么意思| 吃维生素b2有什么好处| 长期喝酒有什么危害| 抑郁症有什么症状| 什么大笑| 什么时候开始| 什么东西不能吃| 陌上人如玉是什么意思| 孩子流口水是什么原因引起的| 荷花和莲花有什么区别| 黑吃黑是什么意思| 为什么会脚臭| 神经官能症有什么症状表现| 农历今天属什么| 增加性功能吃什么药| 漂流需要准备什么东西| 太阳最后会变成什么| 皮肤黑的人穿什么颜色的衣服显白| 佛法无边是什么生肖| 膝关节积液是什么原因造成的| 抑制什么意思| 什么的城堡| 发愿是什么意思| 智齿一般长在什么位置| 70年产权是什么意思| 脑彩超能检查出什么| 1月19号是什么星座| 今天吃什么| 萨德事件是什么意思| 中国发明了什么| 生理期吃什么好| 经常打屁是什么原因| 中国第五大发明是什么| 游走性疼痛挂什么科| 肛门里面疼是什么原因| 九月初八是什么星座| 圣诞节的礼物什么时候送| 道心是什么意思| 大学学什么| 好学不倦什么意思| 糖尿病适合吃什么水果| 胃溃疡有什么症状| 警察代表什么生肖| 牙龈萎缩是什么原因引起的| 戏谑是什么意思| 乳酸是什么东西| 阳痿什么症状| 身上汗味重是什么原因| 猫鼻支什么症状| 花中隐士是什么花| 中央党校什么级别| 云为什么是白色的| 为什么会胃出血| 什么的珍珠| 鼻炎吃什么药见效快| 苦海无涯回头是岸是什么意思| 王八是什么字| 为什么医生不推荐特立帕肽呢| 头发变棕色是什么原因| 单于是什么意思| 大作是什么意思| 倒挂金钩什么意思| 难能可贵是什么意思| 陶渊明是什么朝代| 咳嗽背部疼是什么原因| 青岛啤酒节是什么时候| 早上吃鸡蛋有什么好处| 六月是什么夏| 什么是渡劫| 鲩鱼是什么鱼| 夏天喝什么饮料好| 孕酮低对胎儿有什么影响| 法令纹深代表什么面相| 什么是口腔溃疡| iod什么意思| 七宗罪是什么| 乘风破浪是什么生肖| 化疗后吃什么补白细胞| 糖尿病吃什么水果比较好| 风风火火是什么生肖| 五劳七伤什么生肖| 海带绿豆汤有什么功效| 女人脚肿是什么原因| 脚抽筋什么原因| 梦见被蛇咬了是什么意思| 晚上8点是什么时辰| 糖代谢增高是什么意思| 什么时候吃姜最好| 永加日念什么| 姜子牙是什么神仙| 10年什么婚| 下次闰六月是什么时候| 心电图显示窦性心律是什么意思| 八月一日是什么日子| 小孩出冷汗是什么原因| rma是什么意思| 中秋节适合吃什么菜| 骨密度t值是什么意思| cpr是什么意思| 眼睛干涩痒是什么原因| 回盲瓣呈唇形什么意思| 眼睛散光和近视有什么区别| 嗓子疼是什么原因引起的| 发烧为什么不能吃鸡蛋| 证候是什么意思| 灰指甲是什么原因引起| 蟑螂中药名称叫什么| 乌龟和甲鱼有什么区别| 体制内是什么意思| 脸一边大一边小是什么原因| 谩骂是什么意思| 囊内可见卵黄囊是什么意思| 三元及第是什么意思| 孩子为什么不听话| 什么叫遗精| 个人简历籍贯填什么| 50年是什么婚| 头晕恶心什么原因| 血管造影检查什么| 舌头上有齿痕是什么原因| 什么是苏打水| 蛇配什么生肖最好| 白细胞低要吃什么| 心肌炎是什么病严重吗| 心是什么意思| 无赖不还钱最怕什么| 自勉是什么意思| g6pd筛查是检查什么| 春天什么花会开| 看什么看| 人中龙凤下一句是什么| 绾色是什么颜色| 嬴政为什么要杀吕不韦| 2030年是什么年| 汉武帝属什么生肖| 消肿用什么药| 什么是绿色食品| 石斛什么人不适合吃| 册封是什么意思| pa是什么元素| 7.2号是什么星座| 免疫抑制是什么意思| 梦见自己娶媳妇是什么意思| 顾问是什么意思| 生物素是什么| 银属于五行属什么| 胃胀吃什么药最有效| 鳄鱼怕什么| 低钾血症吃什么食补| 诞辰什么意思| cea升高是什么意思| 股票除权是什么意思| 总是口腔溃疡是什么原因| 拉不出屎吃什么药| EXP什么意思| 6.5是什么星座| 5月31号什么星座| 类风湿吃什么食物好| 白内障是什么症状| 2016属什么生肖| 月经不来挂什么科| 甲鱼蛋什么人不能吃| o型血的父母是什么血型| 波尔多红是什么颜色| 吃什么保养子宫和卵巢| 为什么感冒会咳嗽| 什么是黑户| 怀孕第一个月最怕什么| 解酒喝什么最好| 碧玉是什么玉| 月经量多是什么原因引起的| 人工肝是什么意思| 西梅什么时候成熟| 脸黄是什么原因造成的| 孕吐严重是什么原因| 水金龟属于什么茶| 1月21号是什么星座| 千山暮雪结局是什么| 玖字五行属什么| 牙根疼是什么原因| 嘴下面起痘是什么原因| 检查是否怀孕要做什么检查| 六月飞雪是什么意思| 茯苓不能和什么一起吃| 什么炒腊肉好吃| 什么是冰种翡翠| 我宣你是什么意思| 心电轴不偏是什么意思| 私人订制什么意思| 五级职员是什么级别| 恐惧是什么意思| 为什么手会麻| 地球是什么星| 小姑娘为什么会得多囊卵巢| 胸围85是什么罩杯| 医院打耳洞挂什么科| 捞女是什么意思| 沾沾喜气什么意思| 护肝吃什么药| 口臭应该挂什么科| 米糠是什么| 扁桃体挂什么科| 钢铁侠是什么意思| 大林木是什么生肖| 2025年属什么| 甲胎蛋白是检查什么| 万里晴空什么意思| 秦始皇为什么焚书坑儒| 痤疮用什么药| 荔枝是什么季节的水果| 桃子又什么又什么填空| 宫禁糜烂用什么药| 粘纤是什么材质| 狗鼻子为什么是湿的| 农历六月初三是什么星座| 手指关节痛吃什么药好| 3月3日什么星座| 动情是什么意思| 子宫轻度下垂有什么办法恢复| 睡眠好的人说明什么| mrsa是什么细菌| 4月3号是什么星座| 掏耳朵咳嗽是什么原因| 结肠炎不能吃什么食物| 精尽人亡什么意思| 张姓为什么出不了皇帝| 吃茶油对身体有什么好处| 罗红霉素胶囊治什么病| 牙结石不除有什么危害| 交易是什么意思| 性生活频繁有什么危害| 2段和3段奶粉有什么区别| 左眼皮一直跳什么原因| 君子兰不开花是什么原因| 胃阳不足吃什么中成药| 冬瓜什么季节吃最好| 红曲红是什么| 教授是什么级别| 龟代表什么生肖| ab阳性血型是什么血型| 百度

前端测试 基于 Anyproxy 的 Mock 服务器设计优化升级

terrychow · 2025-08-06 · 最后由 文若 回复于 2025-08-06 · 8154 次阅读

一、前言

  • 最近陆陆续续地有 testerhome 中的朋友加我微信向我请教一些测试技术方案的实现,问得比较多的是 mock 服务器的实现,就是菜鸟搭建 Mock 服务器实践:Anyproxy+Moco,果然这是一个菜鸟搭建的东西,后面请教我的那些朋友都遇到了大坑,我先和所有看之前那套方案的朋友说声对不起,也应了我今年最喜欢说的那句话,去年啥都做,但啥都不精,好吧,不浪费篇幅,今天就特意应一些朋友的请求,也为了统一解答大家的一些疑点,我把后面我经过 5 个版本迭代的 mock 服务器分享给大家,希望对大家能起到那么一丢丢的帮助

二、之前的坑

  • 百度 另一种方案是第7和第10打一场比赛,胜者成为该分区的第7;第8和第9打一场比赛,胜者成为该分区的第8。

    看过上面那篇文的朋友都能了解到,之前的 mock 服务器主要分为 anyproxy 和 moco,后面发现了一系列的严重问题:

    1.moco 中文编码处理很麻烦,而且 moco 起的作用是数据管理部分,那数据管理的话没必要用一个服务器那么重
    2.mock 的 api 写死在代码里面,要改 mock 的 api 时需要改代码和重启服务器,而且其实每次只能 mock 一个 api
    3.如果在测试过程中不需要 mock 时,就必须关掉服务器,那又要去设置一次代理,很麻烦
    4.api 多了之后是否会有性能问题

好,那我的工作又来的,后面就通过 5 个版本的迭代,把上面的 4 个坑感觉还是很好的填了的

三、优化过程

  • 优先是对整个 mock 服务器的架构设计,直接了白

    1、api:管理需要 mock 的接口,可以直接用 txt 来按行管理

    2、data:用于存放要 mock 的数据,可以和 api 一一对应,以 json 文件格式来管理,数据内容是整个 json

    3、conf:用于管理配置文件,目前最主重要的一个配置就是 mock 的开关

还有 tmp 是放在一些临时文件,好,上面的架构基本把接口和 mock 数据从 mock 服务器的代码中分离出来,那接下来就是主核心的 mock 服务器代码

具体的实现代码:

rule_mock.js
global.api = "testapi";   //mock接口标识
module.exports = {

    summary:function(){
        return "replace response data by local response now";
    },

    //mark if use local response
    shouldUseLocalResponse : function(req,reqBody){
      var fs=require('fs')
      var msdata=fs.readFileSync('./conf/ms.json',"UTF-8"); //读取mock开关配置文件
      var ms = JSON.parse(msdata);
      var isOpen = ms['isOpen'];
      if (isOpen==0) {                               //当isOpen为0时,把直接返回false跳过所有mock
        console.log("isOpen is :" +isOpen+",skip mock!");
        return false;
      };
      var file = fs.readFileSync('./api/mock_api.txt',"utf8");  //读取api文件
      var apilist = [];
      apilist=file.split(/\r?\n/ig);            //按行分割存为列表
      for (var i = 0;  i < apilist.length; i++) {    //循环mock,有多少个接口就mock多少次,支持多接口同时mock
        var mockapi=apilist[i];
        if(new RegExp(mockapi).test(req.url)){     //匹配是否为被mock接口
          global.api=mockapi
          return true;
          }
        };
      return false;  
    },

    dealLocalResponse : function(req,reqBody,callback){
            var fs=require('fs');
            console.log('mock api is: '+global.api);//使用global对象访问到"全局"变量
            fs.readFile('./data/mock_data.json',function(err,data){  //读取mock的数据,data为一个json对象
                if(err)  
                    throw err;     
                var arr = JSON.parse(data);
                try{
                  var respon=arr[global.api];  //取出json对象中对应api的数据
                  console.log("status  :" + respon.status);
                  console.log("headers  :" + JSON.stringify(respon.headers));
                  console.log("body  :" + JSON.stringify(respon.body));
                  var newDataStr=JSON.stringify(respon.body);
                  callback(respon.status,respon.headers,newDataStr); //组合成一个全新的响应对象并返回
                }

                catch(e){
                  console.log(e);
                  console.log("you should go to set mock data for api: "+global.api);  //作异常处理,当被mock的接口没有对应的mock数据时,提示并防止服务器退出
                }
            })

    }
};

通过注释来看设计思路就很清晰了,代码里面最核心的两个参数 global.api 和 isOpen,isOpen 用于控制是否要 mock,global.api 就是被 mock 接口和对应 mock 数据的一个关联,通过上面的方式,后面就不再需要通过 moco 来管理 response,直接组合就能解决问题了,通过上面的设计思路,能够解决我上面所提到的坑的前 3 点,好,具体操作来看一下

四,操作演示

  • 通过 anyproxy 来启动服务器执行 mock 脚本和在浏览器设置代理的方法上面文章已经有了,这里就不再演示了,直接验收 mock 过程 1、测试通过 mock 发送消息和对讨论设为关注的接口:cim.msg%3Areply 和 setFlag(接口为已缩写)

以及测试的数据:

{,
"cim.msg%3Areply":
    {"status" : 202,"headers" :{"content-type" : " text/x-json;charset=UTF-8"},"body": {"code":"FA_OVERFLOW","var":{}}},
"setFlag":
    {"status" : 202,"headers" :{"content-type" : " text/x-json;charset=UTF-8"},"body": {"code":"FA_FORBIDDEN","var":{}}}
} 
  • 目前的 mock 开始 isOpen 设置为 0,执行 mock ----------
  • 可以从上面看到,由于 mock 开关已关闭,所有请求都会跳过 ----------
  • 当 isOpen 不为 0 时,开启 mock ----------
  • 可以看到 mock 已生效 ----------
  • 同时可以连续 mock 多个接口,还可以随意增减改需要 mock 的接口,无需重启服务器 ----------
  • 如未对 mock 的 api 设置对应的 mock 数据 ----------
  • 就会有对应的提示,所以不用重启服务器,可以随时修改 mock 数据和 api

所以大致的操作演示就是这样,其实还有第 4 点没说,当被 mock 的接口数到达一定数量时,mock 是否会有性能问题,因为总是整个文件的读,文件量大了,肯定会有问题的,所以就可以通过具体的业务模块的接口来分布到不同的文件中管理,逻辑如下:

分割方法:

rule_mock.dev.js
global.apigroup="testapigroup";

//省略部分已展示过的代码,具体实现逻辑和结合自己项目本身来实现,这个实现方式是我们产品的,未必通用

      try{
        //console.log("req.url is :" +req.url);
        var res=req.url.split('json?func=')[1];
        var useapi=res.split('&sid=')[0];
        //console.log("useapi is :" +useapi);
        global.apigroup=useapi.split('%3A')[0];
        console.log("apigroup is :" +global.apigroup);
      }
      catch(e){
        console.log("api pass");
      }

结合我们论客的接口设计特征,取出业务模块,比如 global.apigroup=cim.msg,然后之后根据 global.apigroup 的值读取对应模块的文件,比如读取 cim.msg.txt,同时加上异常处理

rule_mock.dev.js

//省略部分已展示过的代码
       try{
              var datapath='./data/'+global.apigroup+'.json';
              var filetmp = fs.readFileSync(datapath,"utf8");
            }
            catch(e){
              console.log('mock_data_file"'+global.apigroup+'" is not exist! skip to mock_data');
              var datapath='./data/mock_data.json';
            }

所有最后实现的效果,这样就能优化 mock 服务器的性能,可以看到明确的模块分组

同时对于未模块的 mock 接口,可以直接用回 mock_api 里面的数据,同时会跳过

就这样,我前面所说的 4 个坑就基本填完了

五,最后几句

  • 之前和大家说过的终于写出来了,技术方案要不断地改良,结合业务来实现,才能体现出技术方案的价值,同时也对个人能力的提高起很多的作用,我现在还继续在为我去年的一堆技术方案还债,同时开始着手学习如何制定测试策略,因为没有策略的测试感觉就是瞎测,去年一年没把东西做好做精,很多是由于没有制定出测试策略来指导测试工作的开展,所以也欢迎大家继续共同讨论,共同学习,共同进步,我个人也是很喜欢开分享会的,毕竟分享会最大的受益人是演讲者,这种方式对自己的提升也很快,好吧,有空我可以分享一些作为一名 90 后工作不到 2 年的测试新人是如何学习测试技术和在职场中成长的一些经验,反正就是大家都多聊聊,多点分享,才会进步,谢谢啦
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 12 条回复 时间 点赞
terrychow #1 · 2025-08-06 Author

再给大家开条路,anyproxy 是一个平台,对比 fiddler 和 charles 会更加的通用,我们团队几个人也就只要启动一台 anyproxy 就够了,还可以在 linux 上玩,那意味着可以放到 docker,用 docker 可以同时启动多个代理服务器来分别 mock,而且管理也很方便,不妨试试

之前收藏了帖子,放假刚好找到学习下

—— 来自 TesterHome 官方 安卓客户端

terrychow #11 · 2025-08-06 Author
雪怪 回复

有位朋友和我说目前支持 json 格式的报文,想加入动态支持 xml 的,朋友您也可以考虑一些优化??

"2.mock 的 api 写死在代码里面,要改 mock 的 api 时需要改代码和重启服务器,而且其实每次只能 mock 一个 api", 关于这一点,我看你前一篇帖子是提到修改了 moco 已经 load 的 json, moco 就会重新加载,这不就不用重启了么,而且 api 也是写在 json 里没有写在代码里啊,所以这一点不是很理解,可以再解释一下吗?

terrychow #9 · 2025-08-06 Author
特特兔 回复

是选择的 api 和选择 mock 数据写死在了 rule_mock.js 里面了,每次都只能拿到同一个 mock 数据,理解一下上一篇的逻辑应该就能理解了

terrychow 回复

嗯,前面看的不仔细,以为你说的这点是 moco

anyproxy 使用 http 层,我们这边 网络层通过 jni 实现的,是否有解决之道?

terrychow #6 · 2025-08-06 Author
林家木子 回复

JNI 这种本来 anyproxy 就不支持吧,如果需要做 jni 的 mock,还不如直接在代码上对方法或 api 做,而且最好理解一下 stub 桩服务器和 mock 程序的区别吧,我也是最近才理解区分 stub 和 mock

向阳 用 anyproxy 记录移动端 UI 测试数据 中提及了此贴 09月27日 20:26

666 学习了

学习了,请问关于 response 的模拟,这种该如何实现:POST 请求是 json 报文,其中有一个字段是 ID,response 需要获取这个 ID 作为响应 json 的一部分。

正想搞数据分离的 mock,看了这个有些启发。谢谢

(node:36878) UnhandledPromiseRejectionWarning: TypeError: You may only yield a function, promise, generator, array, or object, but the following object was passed: "replace response data by local response now",您好,启动的时候会报这个警告,但可以启动服务成功,不过 moco 不到指定的 json,啥问题呀,百度了半天没解决

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册
多潘立酮片是什么药 艾灸有什么好处 什么叫免疫力 什么是蓝颜知己 痛风什么原因引起
卵巢囊肿是什么 伟哥是什么 诸位是什么意思 美国为什么那么强大 小孩出汗多是什么原因造成的
雌二醇高说明什么 猪横利是什么 playboy什么意思 cto是什么意思 沾沾喜气什么意思
印度为什么那么热 肾精亏虚是什么意思 排骨汤里放什么食材好 咳嗽干呕是什么原因 车万是什么意思
花重锦官城的重是什么意思hcv7jop7ns4r.cn 11月21日什么星座hcv8jop2ns3r.cn 乳酸菌和益生菌有什么区别hcv9jop0ns7r.cn bc是什么hcv7jop9ns0r.cn 乌鸦飞进家里什么征兆hcv9jop7ns4r.cn
中途疲软吃什么药hcv8jop1ns5r.cn 吃什么肉好hcv7jop9ns4r.cn 什么病不能吃狗肉hcv8jop6ns6r.cn 氨基酸是什么xianpinbao.com 女人耳垂大厚代表什么hcv7jop4ns7r.cn
想睡睡不着是什么原因hcv9jop1ns9r.cn 有两把刷子是什么意思hebeidezhi.com 公报私仇是什么生肖onlinewuye.com 肆虐是什么意思hcv9jop1ns3r.cn 拿手机手抖是什么原因hcv8jop0ns4r.cn
元气是什么hcv8jop8ns7r.cn 马革裹尸是什么意思hcv8jop3ns3r.cn 八败是什么意思hcv8jop2ns8r.cn 梦见偷玉米是什么意思hcv7jop9ns1r.cn 梦见摘西红柿是什么意思naasee.com
百度