接口测试 swagger

jwang · 2019年10月31日 · 1991 次阅读

jmeter 生成 jtl 报告一键部署到 swagger 平台

背景:jmeter 生成 api 报告后,为了方便开发人员跟踪调试错误接口,故搭建 jtl 部署到 swagger 平台。

作用:开发人员可以根据转换后的 swagger,一键执行错误接口,进行重新问题。

1.在生成 jtl 文件前,我们需要对 jmeter 系统文件 user.properties 进行设置。

jmeter.save.saveservice.output_format=xml
jmeter.save.saveservice.response_data=true
jmeter.save.saveservice.samplerData=true
jmeter.save.saveservice.requestHeaders=true
jmeter.save.saveservice.url=true
jmeter.save.saveservice.responseHeaders=true
jmeter.save.saveservice.thread_name=true
jmeter.save.saveservice.response_data.on_error=true

2.jtl 文件转换 swagger.json 脚本

import xml.etree.ElementTree as ET
tree = ET.parse(r'C:\Users\Administrator\Desktop\test.xml')
root = tree.getroot()
data = {}
swagger_json = {}
swagger_json.setdefault("swagger", "2.0")
swagger_json.setdefault("info", {"version": "1.0", "title": "可视化api服务端测试"})
swagger_json.setdefault("tags", [{"name": "visual-controller-fail", "description": "【Jmeter Test Result】 FAILED"},{"name": "visual-controller-pass", "description": "【Jmeter Test Result】 PASS"}])
swagger_json.setdefault("schemes", ["http"])
paths = {}
definitions = {}
httpSamples = root.findall("httpSample")
for i in range(httpSamples.__len__()):
    httpSample = httpSamples[i]
    hattribute = httpSample.attrib
    summary = hattribute.get("lb")
    status = hattribute.get("s")
    rc = hattribute.get("rc")
    if "JDBC" in summary:
        continue
    print(httpSample.findall("method"))
    method = httpSample.findall("method")[0].text
    rcode = hattribute.get("rc")
    header = httpSample.findall("requestHeader")[0].text
    queryString = httpSample.findall("queryString")[0].text
    headers = {}
    for h in header.split("\n"):
        if h != '':
            headers.setdefault(h.split(": ")[0], h.split(": ")[1])
    url = str(httpSample.findall("java.net.URL")[0].text).split(headers.get("Host"))[1]
    model = url.split("/")[-1]
    definition_name = model[0].upper()+model[1:]
    swagger_json.setdefault("host", headers.get("Host"))
    parameters = []
    token = headers.get("Authorization")
    if queryString is not None:
        try:
            body = json.loads(queryString)
            switch = {
                str:"string",
                int:"integer($int32)",
                float:"double",
                dict:"map",
                list:"list",
                tuple:"array",
                bool:"boolean"
            }


            parameters.append({"in":"header","name":"Authorization","default":token,"required":True,"type":"string"})
            parameters.append({"in":"body","name":model,"description":model,"required":True,"schema":{"$ref":'#/definitions/'+definition_name}})
            properties = {}
            for key, value in body.items():
                try:
                    tp = switch[type(value)]
                except KeyError as e:
                    tp = "object"

                properties.setdefault(key,{"type":tp,"example":value})
            definitions.setdefault(definition_name,{"type": "object", "properties": properties, "title": definition_name})

        except Exception as e:
            res = "{\""+ str(queryString).replace("=","\":\"").replace("&","\",\"")+"\"}"
            body = json.loads(res)
            for key, value in body.items():
                if value != '':
                    parameters.append(
                        {"in": "query", "name": key, "default": value, "required": True, "type": "string"})
                else:
                    parameters.append(
                        {"in": "query", "name": key, "default": value, "required": False, "type": "string"})

    else:
        parameters.append(
            {"in": "header", "name": "Authorization", "default": token, "required": True, "type": "string"})
        body = {}
    if status == "true":
        paths.setdefault(url, {
            str(method).lower(): {"responses": {rc: {"description": "OK"}}, "tags": ["visual-controller-pass"],
                                  "summary": summary, "description": "",
                                  "consumes": ["application/json","application/x-www-form-urlencoded; charset=UTF-8"],
                                  "produces": ["application/json"],
                                  "parameters": parameters}})
    if status == "false":
        response_data = httpSample.findall("responseData")[0].text
        paths.setdefault(url, {
            str(method).lower(): {"responses": {rc: {"description": response_data}}, "tags": ["visual-controller-fail"],
                                  "summary": summary, "description": "",
                                  "consumes": ["application/json",
                                               "application/x-www-form-urlencoded; charset=UTF-8"],
                                  "produces": ["application/json"],
                                  "parameters": parameters}})

swagger_json.setdefault("definitions",definitions)

swagger_json.setdefault("paths",paths)
print(swagger_json)
data = json.dumps(swagger_json)
with open("jmeter.json","w",encoding="utf8") as file:
    file.writelines(data)

3.搭建本地 swagger-ui 环境,添加导入 json 文件模块。
3.1.进入官网下载 ui 项目,项目在 github 中的位置:GitHub:Swagger-ui,若 github 也无法访问详见最后文件下载地址。

3.2.下载到本地进行解压,首先看目录结构你可能会懵逼,不要紧,主体部分都放入 dist 目录下,可以进入 dist 目录打开 index.html 看下界面,可以发现基本的模式还是有了,只不过是静态的文件,接下来进行 nodejs 配置,使其可以进行端口访问,直接使用 node 命令访问 index.js 没有反应,英语稍微好点点的同学可以看下官网的配置步骤,接下来手动配置 ui 环境。

3.3.下面进行项目的配置,新建 node_app 文件夹,初始化 node,输入好信息后会自动创建 package.json 文件,如下图:

初始化命令 npm init,出现如下信息,填的地方可以随便写,也可以不写

3.4.将下载的 swagger-ui 中的 dist 文件夹拷贝到 node_app 下:

3.5.安装 express,如果出错可以去 nodejs 安装目录进行安装
>>npm install express

3.6.创建 swagger.js,并将如下代码写入该 js 中

var express = require('express');
var http = require('http');
var app = express();
var fs = require('fs');
var multer = require('multer');
app.set('view engine','ejs');

var createFolder = function(folder){
    try{
        fs.accessSync(folder);
    }catch(e){
        fs.mkdirSync(folder);
    }

};

var uploadFolder = './public/data/';
createFolder(uploadFolder);

var storage = multer.diskStorage({
    destination:function(req,file,cb){
        cb(null,uploadFolder);
    },
    filename:function(req,file,cb){
        cb(null,file.originalname);
    }

});

var upload = multer({storage:storage})

// 接口显示页面
app.use('/static', express.static('public'));
app.listen(8005, function () {
  console.log('app listening on port 8005!');
});
//文件上传
var filename = '';
app.post('/static/index', upload.single('file'), function(req, res, next){
    filename = req.file.originalname;
    res.render('index',{filename:filename});
});

app.get('/static/form', function(req, res, next){
    var index = fs.readFileSync('./public/form.html', {encoding: 'utf8'});
    res.send(index);
});


app.use('/getResponse', function(req, response){

    var headers = {
      'aa': req.headers.aa,
      'xx':req.headers.xx,
      'content-type': req.headers["content-type"]
    };

    if(req.query){
        path = req.path.replace('/getResponse', '')  + "?" + querystring.stringify(req.query)
    }else{
        path = req.path.replace('/getResponse', '')
    }
    var options = {
        hostname: config_data.host,
        path: path,
        headers: headers,
        method: req.method
    };

    var req = http.request(options, function(res) {
        res.setEncoding('utf8');
        res.on('data', function (chunk) {
            response.send(chunk);
            console.log('返回值: ' + chunk);
        });
    });
    req.on('error', function(e) {
        console.log('problem with request: ' + e.message);
    });

    req.write(querystring.stringify(req.body));
    req.end();
   });

app.listen(3000);

3.7 启动 swagger-ui
>>node swagger.js

4.我们打开浏览器进行访问:
http://ip:8005/static/form

5.生成 swagger.json 后上传到 swagger 系统,如下图:

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