Mock工具wiremock-py

作者 | 咪咪

wiremock-py

wiremock-py 是基于WireMock实现的, 使用Python批量生成不同 测试场景 下不同HTTP API的 mock 数据, 然后作为mock server快速全面地对 API 进行测试。

背景

在数澜地产应用的前端测试中, 前端一般依赖于后端的数据, 前端通过后端在网关上发布的 HTTP API 获取数据. 要对前端进行充分的测试, 理想的做法是, 等待后端部署完成, 并且在数据层直接输入不同类型的数据源, 然后前端直接调用后端发布在网关上的 API 进行测试。

Mock工具wiremock-py

然而现实的情况是, 前端和后端的开发进度不完全一致, 如果前端先开发完成了, 必须要等后端对应的 API 开发完成后才能开始测试, 而且数据层的数据也不容易构造。

为了解决这个问题, 网关平台做了简单的 mock 功能, 每个 API 可以填写一个 mock数据, 然后前端调用 API 时直接使用这个 mock数据:

Mock工具wiremock-py

这种方式下, 网关充当了mock server:

Mock工具wiremock-py

但由于大家都使用同一个网关, 一个 API 只能保存一份 mock 数据, 所以有以下一些缺点:

  • 不同的测试场景需要不同的 mock 数据来测试, 此时需要删掉上个测试场景的 mock 数据, 再创建新场景的 mock 数据才能进行测试
  • 不能根据测试场景来按照一定的规则动态生成 API 对应的 mock 数据
  • 不能多人同时使用测试同一个 API时, 只能都使用同一份 mock 数据, 不能各用各的

wiremock-py 可以解决上述这些问题: wiremock-py 通过传入不同的测试场景参数来生成不同的 mock 数据, 同时不同测试场景下使用的 mock 数据可以保存起来; 生成 mock 数据时, wiremock-py 支持使用Python和js代码来动态生成 mock 数据(也支持直接使用 json 数据, 如果 mock 数据中的数据量很大, 人工手写 mock 时的数据量会很大, 使用代码生成则比较容易); 不同的测试人员使用各自自己的 mock server, 不会影响到其他测试人员的测试。

Mock工具wiremock-py

测试人员需要做的是: 确定哪些 API 需要进行 mock 以及不同测试场景下对应的 mock 规则是什么。

依赖环境

Java 1.8.0_144

Node v8.6.0

Python 3.4.3

演示

快速开始

以贸数v1.1.0版本 测试环境为例演示使用 wiremock-py 对楼层客流分布和店铺客流分布两张图分布在3种场景下的测试方法

先确定本地浏览器能过正常访问 http://mall-data.com:9012

准备

克隆代码

git clone http://git.dtwave-inc.com:30000/baomi.wbm/wiremock-py.git

安装依赖

cd wiremock-py

pip install -r requirements.txt

npm install mockjs

生成目录

python mock.py -g "demo"

➜ wiremock-py git:(master)✗ python mock.py -g "demo"

DEBUG:root:mockdir=, scene=, target=, proxy_port=5506, generate=demo, wiremock=False, rewrite=False

DEBUG:root:正在生成目录 /Users/wangbaomi/autotest/wiremock-py/demo

DEBUG:root:创建目录成功: demo

DEBUG:root:创建目录成功: demo/js

DEBUG:root:创建目录成功: demo/json

DEBUG:root:创建目录成功: demo/python

DEBUG:root:创建目录成功: demo/wiremock

DEBUG:root:创建文件成功: demo/mappings.json

DEBUG:root:生成目录完成: /Users/wangbaomi/autotest/wiremock-py/demo

填写 mappings.json、json、python、js 数据

mappings.json 中填写内容:

[

{

    "response": {

        "default": {

            "proxyBaseUrl": "target"

}

},

    "mapping_name": "request url not start with /api",

    "request": {

        "method": "ANY",

        "urlPattern": "/(?!api).*"

    }

},

{

    "mapping_name": "楼层客流分布",

    "request": {

        "urlPattern": "/api/v1/mall_data/customer_flow/every_floor\\?(.*)",

        "method": "POST"

    },

    "response": {

        "default": {

            "proxyBaseUrl": "target"

        },

        "测试场景1": {

            "bodyFileName": {

                "json": "楼层客流分布.json"

            }

        },

        "测试场景2": {

            "bodyFileName": {

                "python": "楼层客流分布.py",

                "python_args": "测试场景2"

            }

        },

        "测试场景3": {

            "bodyFileName": {

                "js": "楼层客流分布.js"

            }

        }

    }

},

{

    "mapping_name": "店铺客流分布",

    "request": {

        "urlPattern": "/api/v1/mall_data/customer_flow/every_shop\\?(.*)",

        "method": "POST"

    },

    "response": {

        "default": {

            "proxyBaseUrl": "target"

        },

        "测试场景1": {

            "bodyFileName": {

                "js": "店铺客流分布.js"

            }

        },

        "测试场景2": {

            "bodyFileName": {

                "json": "店铺客流分布.json"

            }

        },

        "测试场景3": {

            "bodyFileName": {

                "python": "店铺客流分布.py",

                "python_args": "测试场景3"

            }

        }

    }

}

]

js 文件夹中新建店铺客流分布.js文件, 内容为:

var r = {
"success": true,
"code": null,
"message": null,
"content": {
"meta": {},

"multi": {

  "group": [

    {

      "id": "rank",

      "name": "排名",

      "value": [

        1,

        2,

        3,

        4

      ]

    }

  ],

  "result": [

    {

      "id": "the_shop",

      "name": "店铺",

      "value": [

        "店铺1",

        "店铺2",

        "店铺3",

        "第4个店铺"

      ]

    },

    {

      "id": "customer_count",

      "name": "人数",

      "value": [

        10,

        100,

        1000,

        3242

      ]

    }

  ]

},

"single": []
}

};

console.log(JSON.stringify(r));

js 文件夹中新建楼层客流分布.js文件, 内容为:

var r = {

"success": true,

"code": null,

"message": null,

"content": {"meta": {},

"multi": {

  "group": [

    {

      "id": "the_floor",

      "name": "楼层",

      "value": [

        "-1楼",

        "1楼",

        "2楼",

        "3楼",

      ]

    }

  ],

  "result": [

    {

      "id": "customer_count",

      "name": "人数",

      "value": [

        100,

        1000,

        5000,

        567

      ]

    }

  ]

},

"single": []
}

};

console.log(JSON.stringify(r));

json 文件夹中新建店铺客流分布.json, 内容为:

{

"success": true,

"code": null,

"message": null,

"content": {
"meta": {},
"multi": {

相关推荐