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

莫离 · September 24, 2017 · Last by 妖妖 replied at January 14, 2019 · 6483 hits
本帖已被设为精华帖!

- 背景

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 将本帖设为了精华贴 25 Sep 19:54

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

ywzy 回复

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

陈恒捷 回复

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

9Floor has deleted
莫离 回复

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

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 · October 11, 2017 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 · October 15, 2017 Author

是最新的,已加你的 WeChat

莫离 #18 · October 15, 2017 Author

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

19Floor has deleted

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 · November 24, 2017 Author
chanper 回复

再去 git 看~~ 已经改 ORM 了

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

莫离 #24 · November 26, 2017 Author
陈恒捷 回复

好的~ 多谢推荐

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

莫离 #26 · April 03, 2018 Author
JackyRoc 回复

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

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

simple 专栏文章:[精华帖] 社区历年精华帖分类归总 中提及了此贴 13 Dec 14:44

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

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up