Mock Server实践

背景

在美团服务端测试中,被测服务通常依赖于一系列的外部模块,被测服务与外部模块间通过REST API或是Thrift调用来进行通信。要对被测服务进行系统测试,一般做法是,部署好所有外部依赖模块,由被测服务直接调用。然而有时被调用模块尚未开发完成,或者调用返回不好构造,这将影响被测系统的测试进度。为此我们需要开发桩模块,用来模拟被调用模块的行为。最简单的方式是,对于每个外部模块依赖,都创建一套桩模块。然而这样的话,桩模块服务将非常零散,不便于管理。Mock Server为解决这些问题而生,其提供配置request及相应response方式来实现通用桩服务。本文将专门针对REST API来进行介绍Mock Server的整体结构及应用案例。

"mock server背景"

名词解释

  • Mock规则:定义REST API请求及相应模拟响应的一份描述。
  • Mock环境:根据请求来源IP来区分的Mock规则分组。Mock Server可以定义多套Mock环境,各套环境间相互隔离。同一个IP只能对应一个Mock环境,不同的IP可以对应同一个Mock环境。

整体结构

Mock Server由web配置页面Mock Admin及通用Mock Stub组成:Mock Admin提供了web UI配置页面,可以增加/删除请求来源IP到Mock环境的映射,可以对各套环境中的Mock规则进行CRUD操作;Mock Stub提供通用桩服务,对被测系统的各类REST API请求调用,返回预先定义好的模拟响应。为了提高桩服务的通吐,使得桩服务能在被测系统压力测试中得到好的表现,我们开启了5个桩服务,通过Nginx做负载均衡。Mock Server的整体结构如下图所示。

"mock server整体结构"

数据存储

  • 将请求来源IP到Mock环境名的映射存储到mock-env.conf中,mock-env.conf的每一行定义了一条映射,如: 192.168.3.68 闫帅的测试机环境 这条映射表明来源是192.168.3.68的请求,使用Mock环境名为闫帅的测试机环境的Mock规则。
  • 将配置的Mock规则存放到<对应Mock环境名>.xml中,下面部分展示了Mock规则的存储格式。
<configuration>
...<mock id="716add4f-33f7-49ac-abf3-fc617712ffea" name="test001" author="yanshuai"><request><uri>/api/test/.*</uri><method>GET|POST|PUT|DELETE</method><parameters><parameter name="name" value="test.*"/>...</parameters><headers><header name="nb_deviceid" value="1E[0-9a-zA-Z]+"/>...</headers></request><response delay="1000" real="false"><statusCode>200</statusCode><format>application/json;charset=UTF-8</format><customHeaders>...</customHeaders><body>{&quot;name&quot;:&quot;闫帅&quot;}</body></response></mock>
...
</configuration>

Mock Stub

当请求发送到Mock Stub时,Mock Stub会根据请求的来源IP找到对应的独立环境名,然后根据独立环境名获取所有预定义的Mock规则,遍历这些Mock规则,如果找到一条规则与接受到的请求匹配,那么返回预定义的模拟响应。如果找不到规则匹配,那么返回404错误。其中,规则匹配是根据请求中的uri/method/headers/parameters/body是否与Mock规则中定义的对应字段正则匹配来定的。

"mock stub工作原理"

Mock Admin

  • 打开Mock Admin配置页面,如果尚未映射来源IP地址到环境,则点击环境列表导航链接,进入环境列表页面,点击添加,输入源IP及环境名,点击确定按钮,实现源IP到所设环境的映射。
    "mock admin环境列表"

* 点击规则列表,规则列表页面将默认罗列出default环境的所有Mock规则(如“语音登录code获取”规则)。重新选择环境,可以罗列出所选环境中的Mock规则。每个Mock规则都处于详细信息展开的状态。点击“全部折叠”按钮,将把所有的规则详细信息给隐藏;点击“全部展开”按钮,将把所有的规则详细信息给展开。点击“只显示本人创建的规则”,将过滤得到mis账户用户创建的规则。点击“按创建时间排序”的开关按钮,将实现Mock规则的升序/降序显示。
"mock admin规则列表"

* 点击导航栏的“新建规则”选项,可以创建一个Mock规则,需要填写规则名称、请求及响应,并选中环境。对于请求,需要填写URL及勾选Method,如果要求对于符合某种规则的请求才被Mock,则填写对应的Headers/Parameters/Body Like,这些数据都是正则匹配的形式。对于响应,如果勾选了“返回真实响应”,则只需要关注延时(延时是指返回请求需要的sleep时间,单位是毫秒)。此时需要将请求的URL地址给写完整了,需要包含host(IP)及port,不能只是path。如果不勾选“返回真实响应”,则将返回模拟响应。Status Code填写返回码,比如200,404;Format选择返回数据的格式,比如json,html等;还可以返回自定义的Headers及响应的Body。点击新建按钮以后,如果创建成功,则提示成功创建,并跳转到规则列表页面。
"mock admin新建规则"

* 对于一个创建好的Mock规则,可以点击Action下拉菜单,进行操作。如果点击“克隆”,则跳转到“新建规则”页面,并将克隆的Mock规则信息给填充进去;点击“编辑”,则跳转到更新页面,更新页面填充了要编辑的Mock规则信息;点击“删除”,则弹出确认删除对话框,点击确定按钮,将删除此规则;点击取消按钮,则取消删除操作。如果此Mock规则处于详细信息展开状态,则可点击折叠来隐藏详细信息;如果处于详细信息折叠状态,则可点击展开选项,将显示详细信息。上移选项,可以将Mock规则上移一位;下移选项,可以将Mock规则下移一位。
"mock admin规则操作"

使用方式

  1. 修改被测服务的HTTP依赖,将依赖的IP和端口分别设置为mock.ep.sankuai.com和80,并重启被测服务;
  2. 创建Mock规则;
  3. 调用被测服务的API,被测服务将调用Mock服务;
  4. 删除Mock规则(可选)。

编程使用

创建/删除Mock规则,除了可通过Mock Admin页面配置外,Mock Server还提供了SDK方式,用户可以通过编码来使用Mock Server。

* 在Maven工程pom.xml中添加mock-client依赖

<dependency><groupId>com.sankuai.meituan.ep.mockserver</groupId><artifactId>mock-client</artifactId><version>1.0.6</version>
</dependency>
  • 创建/删除Mock规则
// 构造Mock规则
MockRule rule = new MockRule();
rule.setMockName("test-" + System.currentTimeMillis()); // Mock name必须设置
rule.setAuthor("yanshuai"); // author必须设置,设置为代码编写者的mis账号前缀,比如lining03
MockRequest mockRequest = new MockRequest();
mockRequest.setUri("/api/test/" + System.currentTimeMillis()); // Mock请求的uri必须设置
/***  Mock请求的方法必须设置*  如果只有GET请求,则写成GET;*  如果有GET请求及PUT请求,则写成GET|PUT;*  即用|分割请求方法,不能有空格。*/
mockRequest.setMethod("POST|GET");
// 必要的话,设置Mock请求的匹配header
List<MockRequestHeader> mockRequestHeaders = new ArrayList<MockRequestHeader>();
mockRequestHeaders.add(new MockRequestHeader("device", "android2.3"));
mockRequest.setHeaders(mockRequestHeaders);
// 必要的话,设置Mock请求的匹配参数
List<MockRequestParameter> mockRequestParameters = new ArrayList<MockRequestParameter>();
mockRequestParameters.add(new MockRequestParameter("wd", "123.*"));
mockRequestParameters.add(new MockRequestParameter("version", "v1"));
mockRequest.setParameters(mockRequestParameters);
rule.setMockRequest(mockRequest);
MockResponse mockResponse = new MockResponse();
mockResponse.setDelay(1000L); // 设置Mock响应的延时
mockResponse.setStatusCode(200); // 设置Mock响应的状态码
/*** 设置Mock响应的格式* 如果是json返回,则为application/json;charset=UTF-8;* 如果是文本返回,则为text/plain:charset=UTF-8;* 如果是xml返回,则为text/xml;charset=UTF-8;* 如果是html返回,则为text/html;charset=UTF-8。*/
mockResponse.setFormat("application/json;charset=UTF-8");
List<MockResponseHeader> mockResponseHeaders = new ArrayList<MockResponseHeader>(); // 设置Mock响应的header
mockResponseHeaders.add(new MockResponseHeader("customHeaderName", "customHeaderValue"));
mockResponse.setMockResponseHeaders(mockResponseHeaders);
mockResponse.setBody("{\"code\":200}"); // 设置Mock响应的body
rule.setMockResponse(mockResponse);// 创建Mock规则
final MockClient client = new MockClient();
String id = client.addRule("default", rule); // default为环境名,如果使用别的环境,则填写别的环境名// 调用被测服务的API,被测服务将调用Mock服务
// 省略调用代码...// 删除Mock规则
client.removeRule("default", id); // default为环境名,如果使用别的环境,则填写别的环境名

典型案例

  1. 相同Mock环境,同一接口,不同参数,可以有不同的Mock结果 按照下图,依次创建这两条规则(顺序相关),然后在default环境对应的机器上,访问http://mock.ep.sankuai.com/user/v1/info?token=fake,返回{“code”:401,“type”:“sys_err_auth_fail”,“message”:“invalid token”};访问http://mock.ep.sankuai.com/user/v1/info?token=other,返回{“user”: {“id”: 29008301,“mobile”: “15001245907”,“isBindedMobile”: 1}}。
    "案例1_1"

"案例1_2"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/477082.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美团上交开源PromptDet:无需标注,开放世界的目标检测器

文 | 冯承健源 | 极市平台本文提出了一个开放世界的目标检测器PromptDet&#xff0c;它能够在没有任何手动标注的情况下检测新类别&#xff08;如下图绿色检测框&#xff09;&#xff0c;其中提出区域prompt学习方法和针对网络图像的自训练方法&#xff0c;性能表现SOTA。主页&…

Docker系列之二:基于容器的自动构建

自动构建系统是从美团的自动部署系统发展出来的一个新功能。每当开发人员提交代码到仓库后&#xff0c;系统会自动根据开发人员定制的构建配置&#xff0c;启动新的Docker容器&#xff0c;在其中对源代码进行构建&#xff08;build&#xff09;&#xff0c;包括编译&#xff08…

剑指Offer - 面试题56 - I. 数组中数字出现的次数(异或,分组)

1. 题目 一个整型数组 nums 里除两个数字之外&#xff0c;其他数字都出现了两次。请写程序找出这两个只出现一次的数字。 要求时间复杂度是O(n)&#xff0c;空间复杂度是O(1)。 示例 1&#xff1a; 输入&#xff1a;nums [4,1,4,6] 输出&#xff1a;[1,6] 或 [6,1]示例 2&a…

自动驾驶技术简史

文 | Bernard_Han自动驾驶是一个最近在产业界炙手可热的关键词。无论是与人工智能相关的顶级会议还是各大造车厂商甚至各大投资商都为这个成长初期的蓝海产业下注了美好的未来。但是“汽车自动化”的理论与自动驾驶不同&#xff0c;提出至今已有近百年的历史。从最初的遥控到如…

你是什么时候对深度学习失去信心的?

文 | 霍华德源 | 知乎最近几天在知乎上有个问题火了&#xff1a;你是什么时候对深度学习失去信心的&#xff1f;在此推荐一下知乎大V霍华德的回答&#xff0c;以下为原回答。对于深度学习的现状&#xff0c;工业界还是很清楚的。如果没有变革性的突破&#xff0c;弱人工智能时代…

OpenTSDB 造成 Hbase 整点压力过大问题的排查和解决

业务背景 OpenTSDB 是一款非常适合存储海量时间序列数据的开源软件&#xff0c;使用 HBase 作为存储让它变的非常容易扩展。我们在建设美团性能监控平台的过程中&#xff0c;每天需要处理数以亿计的数据&#xff0c;经过几番探索和调研&#xff0c;最终选取了 OpenTSDB 作为数据…

LintCode 183. 木材加工(二分查找)

1. 题目 有一些原木&#xff0c;现在想把这些木头切割成一些长度相同的小段木头&#xff0c;需要得到的小段的数目至少为 k。当然&#xff0c;我们希望得到的小段越长越好&#xff0c;你需要计算能够得到的小段木头的最大长度。 样例 1 输入: L [232, 124, 456] k 7 输出: …

AC算法在美团上单系统的应用

1.背景 在美团&#xff0c;为了保证单子质量&#xff0c;需要对上单系统创建的每一个产品进行审核。为了提高效率&#xff0c;审核人员积累提炼出了一套关键词库&#xff0c;先基于该词库进行自动审核过滤&#xff0c;对于不包括这些关键词的产品信息不再需要进行人工审核。因此…

LintCode 600. 包裹黑色像素点的最小矩形(BFS)

1. 题目 一个由二进制矩阵表示的图&#xff0c;0 表示白色像素点&#xff0c;1 表示黑色像素点。 黑色像素点是联通的&#xff0c;即只有一块黑色区域。 像素是水平和竖直连接的&#xff0c;给一个黑色像素点的坐标 (x, y) &#xff0c;返回囊括所有黑色像素点的矩阵的最小面积…

浙大、阿里提出DictBERT,字典描述知识增强的预训练语言模型

文 | 刘聪NLP源 | NLP工作站写在前面大家好&#xff0c;我是刘聪NLP。今天给大家带来一篇IJCAI2022浙大和阿里联合出品的采用对比学习的字典描述知识增强的预训练语言模型-DictBERT&#xff0c;全名为《Dictionary Description Knowledge Enhanced Language Model Pre-training…

LintCode 207. 区间求和 II(线段树)

1. 题目 在类的构造函数中给一个整数数组, 实现两个方法 query(start, end) 和 modify(index, value): 对于 query(start, end), 返回数组中下标 start 到 end 的 和。对于 modify(index, value), 修改数组中下标为 index 上的数为 value. 样例1 输入: [1,2,7,8,5] [query(0…

深入解析String#intern

在 JAVA 语言中有8中基本类型和一种比较特殊的类型String。这些类型为了使他们在运行过程中速度更快&#xff0c;更节省内存&#xff0c;都提供了一种常量池的概念。常量池就类似一个JAVA系统级别提供的缓存。 8种基本类型的常量池都是系统协调的&#xff0c;String类型的常量池…

想通这点,治好 AI 打工人的精神内耗

文 | 天于刀刀受到疫情影响&#xff0c;今年公司的校招生报道日还未到来&#xff0c;23 年的秋招提前批就已经是如火如荼地开展。而诸神黄昏算法岗&#xff0c;作为招聘中最靓眼的仔&#xff0c;简历门槛早已是硕士打底博士起步&#xff0c;项目竞赛多多益善的情况了。面临着今…

DHL

有句俗语谓&#xff1a;“不看不知道&#xff0c;一看吓一跳”&#xff0c;这次通过“中外运-敦豪”的一次快递&#xff0c;亲身感受到这种“吓一跳”的滋味。 MS 总部从 1 月 26 日寄出 MVP Award 快递包之后&#xff0c;在随后的电子邮件中给出了每个人的 DHL 快件追踪号&…

数据结构--树--线段树(Segment Tree)

文章目录1. 概念2. 建树3. 查询4. 修改5. 完整代码及测试上图 from 熊掌搜索 类似数据结构&#xff1a;树状数组 1. 概念 线段树是一种二叉树&#xff0c;是用来表示一个区间的树&#xff1a; 常常用来查询区间的&#xff1a;和、最小值、最大值树结点中存放不是普通二叉树的…

神经网络可视化有3D版本了,美到沦陷!(已开源)

源 |量子位做计算机视觉&#xff0c;离不开CNN。可是&#xff0c;卷积、池化、Softmax……究竟长啥样&#xff0c;是怎样相互连接在一起的&#xff1f;对着代码凭空想象&#xff0c;多少让人有点头皮微凉。于是&#xff0c;有人干脆用Unity给它完整3D可视化了出来。还不光是有个…

CentOS6上Hadoop集群中服务器cpu sys态异常的定位与解决

问题现象 在zabbix系统中&#xff0c;对Hadoop集群的历史监控数据分析时&#xff0c;发现在执行大Job任务时&#xff0c;某些服务节点的cpu sys态很高&#xff1b;具体以hadoop_A服务节点为例&#xff0c;在10:15-10:40这个时间段&#xff0c;cpu user态为60%&#xff0c;而sys…

偶也Blog了

欢迎大家和我交流…………转载于:https://www.cnblogs.com/dsclub/archive/2004/06/18/16753.html

LintCode 1692. 组队打怪(田忌赛马,二分查找)

1. 题目 你现在有n个英雄&#xff0c;每个英雄的战斗力为 atk1,你要用这些英雄去对付n个怪物&#xff0c;每个怪物的战斗力为atk2。 在一场战斗中&#xff0c;你需要安排每个英雄分别与一个怪兽战斗&#xff0c;如果英雄战斗力高于怪兽&#xff0c;那个怪兽就会被击杀&#xf…

谷歌搜索,全球宕机??

文 | 好困源 | 新智元忽然之间&#xff0c;谷歌搜索&#xff0c;挂了。美东时间周一晚上9点&#xff08;北京时间周二早上9点&#xff09;左右&#xff0c;有不少用户突然发现自己上不去谷歌了。对于这次谷歌的突然宕机&#xff0c;网友们完全没有任何的心理准备。「谷歌停止工…