通用技术 [分享] 自己写的 mock 管理平台 simple_mock

莫离 · 2017年09月24日 · 最后由 妖妖 回复于 2019年01月14日 · 332 次阅读
本帖已被设为精华帖!

- 背景

1、由于最近需要做一些和第三方对接的功能测试,部分第三方的返回结果无法模拟或者模拟效率低,导致部分场景无法测试。
2、所在部门前后端分离,但 web 进度常年领先后端,而 web 开发自己又懒得写 UT。导致最后经常在 SIT 缓解暴露问题,提供一个平台方便他们自己进行 UT。
3、部分自动化测试需要依赖 mock 进行,传统的 mock 数据修改和管理又不是那么集中以及友好。

- 调研

google 了一些工具,没找到什么太适合的,于是还是决定自己写个(重复造个轮子)吧。

- 整体思路

1、采用的是 python+flask,根据请求的内容进行解析结果,然后在数据库中进行数据的校验和匹配,返回预期结果。
2、mock_server 进行请求的接收和响应,mock_web 提供和 web 端交互的接口。
3、目前功能:提供增删改查、复制、excel 导入、禁用/启用等功能。

  • 下边直接上图和 git 地址


  • DEMO

  • 部分核心代码

def checkpath(domain,varsvalue,method):
    method=method.lower()
    varsvalue.sort()
    checksize(domain,method)#判断请求方法和模式是否匹配
    if len(varsvalue) == 0:
        conn = pymysql.connect(**config)
        cur = conn.cursor()
        cur.execute('select resparams from mock_config where status=0 and domain=%s and methods=%s', (domain, method))
        resparams = cur.fetchone()
        conn.close()
        if resparams[0] == '':
            return jsonify({"msg": "对应请求没有配置预期返回值"})
        else:
            return resparams[0].encode("utf-8")
    else:
        varsvalue1=getvar(varsvalue)#实际请求
        conn = pymysql.connect(**config)
        cur = conn.cursor()
        cur.execute('select reqparams,resparams,methods,ischeck from mock_config where status=0 and domain=%s and methods=%s',(domain, method))
        reqparams = cur.fetchall()
        if reqparams == ():
            return jsonify({"msg": u"请求方法和参数不匹配"})
        elif reqparams[0][3]==1:
            return reqparams[0][1]
        else:
            rdata=checkparams(reqparams,varsvalue1)
        return rdata

def checkparams(reqparams,varsvalue1):
    varsvalue2 = reqparams[0][0]  # 数据库中的预期请求参数
    if reqparams[0][2].lower()=='get' or (reqparams[0][2].lower()=='post' and varsvalue1[0] != '}' and varsvalue1[-2] != '}'):
        arr = varsvalue2.split('&')
        for i in range(len(arr)):
            arr[i] = arr[i] + '&'
        arr.sort(reverse=True)
        str = ''.join(arr)[0:-1]
        if str==varsvalue1:
            return reqparams[0][1].encode("utf-8")
        if reqparams[0][0] == '':
            return jsonify({"msg": u"对应请求没有配置预期返回值"})
        else:
            return jsonify({"msg": u"请求方法和参数不匹配"})
    elif reqparams[0][2].lower()=='post':
        varsvalue1 = varsvalue1.replace("\t", "").replace("\r", "").strip()[:-1]
        varsvalue2 = varsvalue2.replace("\t", "").replace("\r", "").strip()
        if varsvalue1 == varsvalue2:
            return reqparams[0][1].encode("utf-8")
    else:
        return jsonify({"msg": u"暂不支持该类型请求方法"})
  • git 地址 现已开源

    https://github.com/r455678/simple_mock

  • 使用须知:

    1、使用前需安装依赖库。
    2、20170824.xlsx 为导入模板。
    3、数据库信息配置在 db.config 文件。
    4、mock_config.sql 为数据库建表语句。
    5、web 端配置地址在 mock/js/config.js 文件中。

  • PS:

    1、如果使用过程中存在问题或者 bug 建议提 issue,最近 996 了可能无法第一时间回复。
    2、其实写好了有一段时间了,like 通配符那有个 sql 注入的漏洞一直没时间修复。
    3、还是希望能帮助到有需要的同学们,如果有更好的 idea 也欢迎提出来。
    4、另虽然 mock 的话更加注重的是 mock 本身的思想已经运用场景,但是有个贴合实际场景的平台的话还是会事半功倍的。

- 又到一年入学季,同时也为自己远走他乡第十个年头 Mark 一下,不忘初心方得始终!

共收到 25 条回复 时间 点赞

mock 在特殊场景测试还是蛮好用的。
但是个人觉得 如果用到 UI 自动化,如果接口变动,维护接口参数、response,感觉挺麻烦的

李海默 回复

设计了两种模式:
A、不校验请求参数,可以只维护 response 的 content。
B、填写多条,每次通过禁用启用的方式管理。

这个点赞,思路和我的一致……

服务启动后,提示:网址为 http://0.0.0.0:5201/ 的网页可能暂时无法连接,或者它已永久性地移动到了新网址。

思寒_seveniruby 将本帖设为了精华贴 09月25日 11:54

挺不错的,想问下有考虑支持 callback 类型的 mock 不?不少第三方是通过 callback 的方式返回数据的。

ywzy 回复

是这样的,管理页面没和项目做集成,要单独部署在 web 容器里。主页是 index.html

陈恒捷 回复

暂时没有,看 10 月份再说。。。。。

9楼 已删除
莫离 回复

能否具体说下方法(操作步骤)呢?谢谢

莫离 #11 · 2017年09月27日 Author
ywzy 回复

1、执行 sql 脚本建表
2、修改 db.config 数据库配置文件
3、安装需要的第三方依赖库,运行 mock_server.py。
4、运行 mock_web.py。
5、把 web 项目拷贝到 web 容器中正常访问,修改 mock/js/config.js 接口访问地址为 mock_web 的地址和端口。
6、打开 index 页,添加/导入自己需要的 mock 数据。

莫离 回复

感谢~😀

莫离 回复

1、执行 sql 脚本建表

2、修改 db.config 数据库配置文件

3、安装需要的第三方依赖库,运行 mock_server.py。
4、运行 mock_web.py。

5、把 web 项目拷贝到 web 容器中正常访问,修改 mock/js/config.js 接口访问地址为 mock_web 的地址和端口。
这句话不了解,web 容器是指的什么?能否具体说明

6、打开 index 页,添加/导入自己需要的 mock 数据。

莫离 #14 · 2017年10月11日 Author
大海 回复

5、比如 nginx tomcat IIS 等

@r455678 首先你初始化 sql 里面,那个 insert 语句有问题了,增加的 values 值少了一个 status 的值,我看下你源码没发现是干嘛用的,但你在帖子里面 checkpath 方法缺有一个 status=0,所以给你默认设置了一个 0;

INSERT INTO mock_config.mock_config VALUES ('1', '请求登陆11', 'var1=1&var2=2&var3=3', 'post', '/login/manageLogin2',  'var1=1&var2=2&var3=3', '{\"status\":\"fail\",\"msg\":\"111用户名或密码错误,密码输错超过5次将被锁定哦!已输错1次\",\"data\":\"\",\"externData\":null}',  '2017-08-10 17:54:05','0', '0', '营销平台');

@r455678
你 mock_server.py 的 def _getexcelparas 这个方法的名称单词写错了吧?

晚上花了点时间看了下楼主的源码,有些问题以及一些 idea 方便的话跟你交流下,我可以协助你提交掉代码以及一些代码的 bug 修复

莫离 #17 · 2017年10月15日 Author

是最新的,已加你的 WeChat

莫离 #18 · 2017年10月15日 Author

status 是作为是否启用的状态,sql 里不是 status 没 value,是 ischeck 字段改了代码没改 sql 脚本。
PS:既然已经开源,欢迎改代码,不用和我说。

19楼 已删除

sql = "select id,status,title,reqparams,methods,domain,description,resparams,date_format(update_time,'%%Y-%%m-%%d %%H:%%i:%%s') from mock_config where title like %s"
sql = "select id,status,title,reqparams,methods,domain,description,resparams,date_format(update_time,'%%Y-%%m-%%d %%H:%%i:%%s') from mock_config where title like %s and project_name=%s"
此处的 sql 是不是写的有问题,select * from table where title like %xx% 类似这种格式?

我觉得 MOCK 测试的话 推荐 eoLinker 也很好用

莫离 #22 · 2017年11月24日 Author
chanper 回复

再去 git 看~~ 已经改 ORM 了

最近开始用一个国内开源的 easy_mock ,感觉功能也挺不错的,建议楼主可以试用下,看能不能找到一些灵感。

莫离 #24 · 2017年11月26日 Author
陈恒捷 回复

好的~ 多谢推荐

感谢开源分享,请问 simple_mock 是否支持这样的场景:POST 请求是 json 报文,其中有一个字段是 ID,response 需要获取这个 ID 作为响应 json 的一部分。谢谢,我看了很多 mock 工具都不支持

莫离 #26 · 2018年04月03日 Author
JackyRoc 回复

暂不支持。。。建议通过自己做参数提取器实现。

你好 mock 生成的服务的 url 是什么样的组合?

simple 专栏文章:[精华帖] 社区历年精华帖分类归总 中提及了此贴 12月13日 06:44
simple [精彩盘点] TesterHome 社区 2018 年 度精华帖 中提及了此贴 01月07日 04:08

准备拿来学习下,感谢分享

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册