用python写一个并发测试工具

工作中会有一些需要并发测试的场景,例如:两人同时操作一条数据,此时需要验证结果是否符合预期

 

最初是借助jmeter来进行并发测试,建2个线程组,每个线程组中各放一个接口,启动时会同时执行个线程组中的接口,从而实现并发测试的目的

但是每次都要打开jmeter,用起来不太方便,所以就尝试用python来实现接口并发测试,然后再写个前端页面

所以本次实现以下功能:

1、后端在django框架下,基于python实现接口并发测试

2、前端页面基于百度amis低代码平台实现

一、后端逻辑实现

用python自带的库concurrent.futures,它提供ThreadPoolExecutor,使之能够并发执行函数(来自ChatGPT)

ChatGPT给出的示例代码如下

上述代码中,make_request()函数是需要并发执行的函数,ThreadPoolExecutor设置并发请求,示例中传入的参数urls是一个list

根据自己的实际需求改造一下示例代码:

首先我的目标是对2个接口请求进行并发测试,所以会从前端传入2个接口的请求url、headers、请求参数,把前端参数组合成list,大致如下:列表包裹字典,一个字典是一组参数,标记好url、headers、payload

    param_data = [
        {"url": url_1, "headers": headers_1, "payload": payload_1},
        {"url": url_2, "headers": headers_2, "payload": payload_2}
    ]

新建一个concurrency_test.py文件

make_request()函数改为如下形式,它接收的参数data就是一组字典参数

from concurrent.futures import ThreadPoolExecutor
import requests


def make_request(data):
    r = requests.post(url=data["url"], headers=data["headers"], json=data["payload"], verify=False)
    # print(r.json())
    return r.json()

然后再定义一个主函数

def multi_processing(data):
    with ThreadPoolExecutor(max_workers=2) as executor:
        results = list(executor.map(make_request, data))
    # print(results)
    res = []
    for i, result in zip(data, results):
        res.append(
            result["message"] + ";traceId=" + result["traceId"]
        )
    print(res)

    return res

max_workers控制并发数量(线程数),map()中接收并发函数以及它所需要的参数

 

再新建一个视图函数concurrency_test_views.py

from django.http import JsonResponse,HttpResponse
import json
from app.api.concurrency_test import *
from django.views.decorators.http import require_http_methods


def concurrent(request):
    url_1 = request.GET.get("url_1")

    headers_1 = json.loads(request.GET.get("header_1"))
    payload_1 = json.loads(request.GET.get("body_1"))

    url_2 = request.GET.get("url_2")
    headers_2 = json.loads(request.GET.get("header_2"))
    payload_2 = json.loads(request.GET.get("body_2"))

    param_data = [
        {"url": url_1, "headers": headers_1, "payload": payload_1},
        {"url": url_2, "headers": headers_2, "payload": payload_2}
    ]

    res = multi_processing(param_data)
    dict_res = {
        "res1": res[0],
        "res2": res[1]
    }
    return JsonResponse(dict_res, json_dumps_params={'ensure_ascii': False})
    # return HttpResponse(res)

最后配置好路由,这个接口就写好了

----------------------------------------------

接下来开始写前端,前端布局大致如下

这个页面是直接用amis写的,这部分是用的现成的组件,不再细说,贴下代码

前端amis代码
<template>
    <div ref="box" style="text-align: center; font-size: 24px; font-weight: 700; margin-bottom: 20px">
      基本信息
    </div>
  </template>
  <script>
  export default {
    mounted() {
      const amis = amisRequire('amis/embed')
      let url = this.COMMON.test_url
      let amisJSON = {
        "type": "page",
        "title": "工具类",
        "remark": "",

        "body": [
            {
                "type": "tabs",
                "tabs": [
                    {
                        "title": "接口并发测试",
                        "hash": "tab1",
                        "body": [
                            
                            {
                                "type": "grid",
                                "columns": [

                                    {
                                        // "type": "wrapper",
                                        // "style": {
                                        //     "width": "600px"
                                        // },

                                        "body": [
                                            // {
                                            //     "type": "wrapper",
                                            //     // "title": "面板标题",
                                            //     "body": "面板内容"
                                            // },
                                            
                                            {
                                            "type": "form",
                                            "style": {
                                            
                                                },
                                            "title": "并发测试工具",
                                            "mode": "horizontal",
                                            "autoFocus": false,
                                            "horizontal": {
                                                "leftFixed": "md"
                                            },


                                            "body": [

                                                {
                                                    "type": "group",
                                                    "label": "Request URL",
                                                    "body": [
                                                        {
                                                            "type": "input-text",
                                                            "size": "",  //控制输入框大小
                                                            "placeholder": "请输入第一个接口url",
                                                            "clearable": true,  //设置可清除输入内容
                                                            "required": true,
                                                            // "showCounter": true,
                                                            // "maxLength": 11,  //限制最大字数
                                                            "name": "url_1",
                                                            "value": "",
                                                            "label": false
                                                        },
                                                        {
                                                            "type": "input-text",
                                                            "size": "",  //控制输入框大小
                                                            "placeholder": "请输入第二个接口url",
                                                            "clearable": true,  //设置可清除输入内容
                                                            "required": true,
                                                            // "showCounter": true,
                                                            // "maxLength": 11,  //限制最大字数
                                                            "name": "url_2",
                                                            "value": "",
                                                            "label": false
                                                        }
                                                    ]
                                                },
                                                {
                                                    "type": "group",
                                                    "label": "Headers",
                                                    "body": [
                                                        {
                                                            "type": "textarea",
                                                            "size": "",
                                                            "placeholder": "请输入第一个接口的headers",
                                                            "required": true,
                                                            "clearable": true, 
                                                            "name": "header_1",
                                                            "value": "",
                                                            "label": false
                                                        },
                                                        {
                                                            "type": "textarea",
                                                            "size": "",
                                                            "placeholder": "请输入第二个接口的headers",
                                                            "required": true,
                                                            "clearable": true, 
                                                            "name": "header_2",
                                                            "value": "",
                                                            "label": false
                                                        }
                                                    ]
                                                },
                                                {
                                                    "type": "group",
                                                    "label": "Payload",
                                                    "body": [
                                                        {
                                                            "type": "textarea",
                                                            "size": "",
                                                            "placeholder": "请输入第一个接口的请求参数",
                                                            "required": true,
                                                            "clearable": true, 
                                                            "name": "body_1",
                                                            "value": "",
                                                            "label": false
                                                        },
                                                        {
                                                            "type": "textarea",
                                                            "size": "",
                                                            "placeholder": "请输入第二个接口的请求参数",
                                                            "required": true,
                                                            "clearable": true, 
                                                            "name": "body_2",
                                                            "value": "",
                                                            "label": false
                                                        }
                                                    ]
                                                },

                                                // json展示返回结果
                                                {
                                                    "type": "control",
                                                    "css": {
                                                    ".myClass": {
                                                        "color": "black",
                                                        "font-size": "15px",
                                                        "font-weight": "normal",
                                                        "text-align": "left",
                                                        // "display": "inline-block"
                                                        }
                                                    },
                                                    "name": "res",
                                                    "label": "接口返回结果",
                                                    "body": {
                                                        "type": "json",
                                                        "levelExpand": 100,
                                                        "className": "myClass"
                                                    }
                                                }
                                                // {
                                                //     "name": "res",
                                                //     "type": "static",
                                                //     "label": "返回结果",
                                                //     "value": ""
                                                // }
                                            ],
                                            "actions": [
                                                {
                                                    "//": "type为submit时, 表示该按钮是一个行为按钮, 点击可以提交请求",
                                                    "type": "submit",

                                                    "label": "提交",

                                                    "//": "level配置按钮颜色, https://aisuda.bce.baidu.com/amis/zh-CN/components/action?page=1#%E4%B8%BB%E9%A2%98",
                                                    "level": "primary",

                                                    "api": {
                                                        "method": "get",
                                                        "url": url+"data_factory/concurrent",
                                                        "data": {
                                                            "url_1": "${url_1}",
                                                            "header_1": "${header_1}",
                                                            "body_1": "${body_1}",
                                                            "url_2": "${url_2}",
                                                            "header_2": "${header_2}",
                                                            "body_2": "${body_2}",
                                                        },
                                                        "adaptor": "return {\n data: {\n res: response.data\n}\n}"
                                                    }
                                                },

                                                {
                                                    "type": "reset",
                                                    "label": "重置"
                                                }
                                            ]
                                        }
                                        ]
                                    }
                                ]
                            },
                            
                            {
                                "type": "grid",
                                "columns": [
                                {
                                            "type": "page",
                                            "title": "使用说明",
                                            "css": {
                                                ".myClass": {
                                                "color": "black",
                                                "font-size": "15px",
                                                "font-weight": "normal",
                                                "text-align": "left",
                                                "display": "inline-block"
                                                }
                                            },
                                            "body": [{
                                                "type": "tpl",
                                                "tpl": "<ul><li>支持对接口进行并发测试</li><li>输入2个接口的请求url、headers、入参</li><li>【请求头】和【请求参数】均为json格式,示例如下</li></ul>",
                                                "className": "myClass"
                                            },
                                            {
                                                    "type": "group",
                                                    "label": "Headers + Payload",
                                                    "body": [
                                                        {
                                                            "type": "textarea",
                                                            "value": '{\n    "Content-Type":"application/json",\n    "Cookie":"",\n    "":"",\n    "param": ""\n}',
                                                            "label": false
                                                        },
                                                        {
                                                            "type": "textarea",
                                                            "value": '{\n    "Content-Type":"application/json;",\n    "Cookie":"",\n    "param":"",\n    "param": ""\n}',
                                                            "label": false
                                                        },
                                                        {
                                                            "type": "textarea",
                                                            "value": '{\n    "Content-Type":"application/json; charset=UTF-8",\n    "Token":"",\n    "param":"",\n}\n',
                                                            "label": false
                                                        },
                                                        {
                                                            "type": "textarea",
                                                            "value": '{\n    "param":"",\n    "param":""\n}\n \n',
                                                            "label": false
                                                        }
                                                    ]
                                                },
                                        ]
                                        }
                                ]
                            }
                        ]
                    },

                    {
                        "title": "其他",
                        "hash": "tab5",
                        "body": 
                        "开发中"
                    }
                ]
            }

        ]
    }
      const amisScoped = amis.embed(this.$refs.box, amisJSON)
    }
  }
  </script>

 

posted @ 2024-02-08 10:20  我是冰霜  阅读(466)  评论(0编辑  收藏  举报