通过swagger自动生成jmeter脚本

引言

之前介绍过怎么通过swagger自动生成接口自动化测试脚本,具体内容《VUE+Java+swagger+okhttp3,实现自动获取接口信息+接口自动化测试》。现在介绍一下,通过swagger获取的接口信息怎么生成jmeter脚本。

获取接口信息

通过swagger获取接口信息,使用SwaggerParser,可以通过swagger接口获取,也可以通过apifox导出的swagger文档获取接口信息。

//解析swagger
Swagger swagger =  new SwaggerParser().parse(jsonObject.toString());
//获取IP和端口
String apiHost = swagger.getHost();
//获取所有接口地址
Map pathsMap = swagger.getPaths();
//获取所有实体类
Map definitionsMap = swagger.getDefinitions();

获取接口信息后,需要解析信息,保存到数据库。

配置jmeter

引入jmeter包

使用Maven引用jmeter

        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_core</artifactId>
            <version>5.4.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.jmeter/ApacheJMeter_java -->
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_java</artifactId>
            <version>5.4.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_http</artifactId>
            <version>5.4.3</version>
        </dependency>

配置jmeter

需要下载jmeter并解压到本地,下载地址jmeter

//初始化 JMeter 环境:
JMeterUtils.loadJMeterProperties("本地jmeter配置文件");
JMeterUtils.setJMeterHome("本地jmeter的bin目录");
JMeterUtils.initLocale();

生成jmeter脚本

根据swagger获取的接口信息,来生成jmeter脚本

package com.zkx.api.common;

import com.alibaba.fastjson.JSONObject;
import com.zkx.api.dao.ApiMapper;
import com.zkx.api.dao.CaseMapper;
import com.zkx.api.dao.DataMapper;
import com.zkx.api.dao.HeaderMapper;
import com.zkx.api.dto.ApiDto;
import com.zkx.api.service.CaseService;
import com.zkx.api.vo.ApiVo;
import com.zkx.api.vo.DataVo;
import com.zkx.api.vo.HeaderVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.jmeter.assertions.ResponseAssertion;
import org.apache.jmeter.assertions.gui.AssertionGui;
import org.apache.jmeter.control.LoopController;
import org.apache.jmeter.control.gui.LoopControlPanel;
import org.apache.jmeter.control.gui.TestPlanGui;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.protocol.http.control.Header;
import org.apache.jmeter.protocol.http.control.HeaderManager;
import org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui;
import org.apache.jmeter.protocol.http.gui.HeaderPanel;
import org.apache.jmeter.protocol.http.sampler.HTTPSampler;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
import org.apache.jmeter.protocol.http.util.HTTPArgument;
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
import org.apache.jmeter.reporters.ResultCollector;
import org.apache.jmeter.reporters.Summariser;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.threads.SetupThreadGroup;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jmeter.threads.gui.ThreadGroupGui;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jmeter.visualizers.RespTimeGraphVisualizer;
import org.apache.jmeter.visualizers.SummaryReport;
import org.apache.jmeter.visualizers.ViewResultsFullVisualizer;
import org.apache.jorphan.collections.HashTree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;

@Slf4j
@Component
public class JMeterTest {

    @Autowired
    ApiMapper apiMapper;

    @Autowired
    DataMapper dataMapper;

    @Autowired
    HeaderMapper headerMapper;

    @Autowired
    CaseService caseService;

    @Autowired
    CaseMapper caseMapper;

    @Value("${jmeter.home}")
    private String jmeterHome;

    @Value("${jmeter.file}")
    private String jmeterFile;

    @Value("${jmeter.properties}")
    private String jmeterProperties;

    @Value("${jmeter.nginx}")
    private String jmeterNginx;

    public  RespBean createJMeterFile(int apiId) throws IOException {
        //初始化 JMeter 环境:
        JMeterUtils.loadJMeterProperties(jmeterProperties);
        JMeterUtils.setJMeterHome(jmeterHome);
        JMeterUtils.initLocale();
        //查询API信息
        ApiVo apiVo = apiMapper.findApiById(apiId);
        //查询接口名称
        String apiName = apiVo.getName();
        //查询接口地址
        String apiUrl = apiVo.getUrl();
        //查询请求方法
        String apiMethod = apiVo.getMethod();
        //查询参数信息
        List<DataVo> dataList = dataMapper.findDataByApiId(apiId);
        //查询请求头信息
        List<HeaderVo> headerVoList = headerMapper.findHeaderByApiId(apiId);
        //创建测试计划
        TestPlan testPlan = createTestPlan(apiName);
        //创建线程组
        SetupThreadGroup threadGroup = createThreadGroup();
        //添加json请求头
        HeaderVo headerVo = new HeaderVo();
        if (apiVo.getData_type().equals("json")) {
            headerVo.setKey("Content-Type");
            headerVo.setValue("application/json;charset=UTF-8");
            headerVoList.add(headerVo);
        }
        //创建请求头管理器
        HeaderManager headerManager = createHeaderManager(headerVoList);
        //创建循环控制器
        LoopController loopController = createLoopController();
        //将循环控制器添加到线程组中:
        threadGroup.setSamplerController(loopController);
        //创建树
        HashTree subTree = new HashTree();
        //创建http文件
        HTTPFileArg httpFileArg = new HTTPFileArg();
        //创建HTTP请求管理器
        HTTPSampler httpSampler = createHTTPSampler(apiUrl,apiMethod);
        //根据请求数据类型,添加测试组件
        if (null != apiVo.getData_type()){
            if (apiVo.getData_type().equals("json")){
                HTTPArgument httpArgument = createHTTPArgument(dataList);
                httpSampler.getArguments().addArgument(httpArgument);
            }else if (apiVo.getData_type().equals("form-data")) {
                for (DataVo dataVo : dataList) {
                    if (null != dataVo.getType()) {
                        if (dataVo.getType().equals("file")) {
                            httpFileArg.setPath(dataVo.getKey());
                            httpFileArg.setParamName(dataVo.getFile_path());
                            httpSampler.setHTTPFiles(new HTTPFileArg[] {httpFileArg});
                        }else {
                            httpSampler.addArgument(dataVo.getKey(),dataVo.getValue());
                        }
                    }
                }
            }else if (apiVo.getData_type().equals("form-urlencoded")) {
                for (DataVo dataVo : dataList) {
                    httpSampler.addArgument(dataVo.getKey(),dataVo.getValue());
                }
            }
        }

        threadGroup.addTestElement(headerManager);
        threadGroup.addTestElement(httpSampler);
        subTree.add(threadGroup,httpSampler);


        //创建总结报告
        Summariser summariser = new Summariser();
        ResultCollector resultCollector = createResultCollector(summariser,1,apiName);
        ResultCollector responseTime = createResultCollector(summariser,2,apiName);
        ResultCollector resultTree = createResultCollector(summariser,3,apiName);
        ResponseAssertion responseAssertion = createResponseAssertion(caseMapper.findExpectResultByApiId(apiId));



        //将线程组添加到测试计划中:
        testPlan.addThreadGroup(threadGroup);

        //创建tree生成jmx脚本
        subTree.add(threadGroup,headerManager);
        subTree.add(threadGroup,resultCollector);
        subTree.add(threadGroup,responseTime);
        subTree.add(threadGroup,resultTree);
        subTree.add(threadGroup,responseAssertion);

        HashTree tree = new HashTree();
        tree.add(testPlan,subTree);
        SaveService.saveTree(tree, new FileOutputStream(jmeterFile + apiName +".jmx"));
        ApiDto apiDto = new ApiDto();
        apiDto.setId(apiId);
        apiDto.setJmeter_file(jmeterFile + apiName +".jmx");
        apiMapper.updateApi(apiDto);
        log.info("生成jmeter脚本成功",jmeterFile + apiName +".jmx");
        return RespBean.ok("生成jmeter脚本成功",jmeterNginx + apiName +".jmx");
    }

    private LoopController createLoopController() {
        LoopController loopController = new LoopController();
        loopController.setName("循环控制器");
        loopController.setLoops(10);
        loopController.setFirst(true);
        loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
        loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
        return loopController;
    }

    private TestPlan createTestPlan(String name) {
        TestPlan testPlan = new TestPlan(name);
        testPlan.setFunctionalMode(false);
        testPlan.setTearDownOnShutdown(true);
        testPlan.setComment("");
        testPlan.setSerialized(false);
        testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
        testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
        return testPlan;
    }

    private SetupThreadGroup createThreadGroup() {
        SetupThreadGroup threadGroup = new SetupThreadGroup();
        threadGroup.setName("线程组");
        threadGroup.isEnabled();
        threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
        threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
        threadGroup.setNumThreads(1);
        threadGroup.setRampUp(0);
        return threadGroup;
    }

    private HeaderManager createHeaderManager(List<HeaderVo> lists) {
        HeaderManager headerManager = new HeaderManager();
        headerManager.setName("请求头管理器");
        headerManager.isEnabled();
        headerManager.setProperty(TestElement.TEST_CLASS, HeaderManager.class.getName());
        headerManager.setProperty(TestElement.GUI_CLASS, HeaderPanel.class.getName());
        if (lists.size() > 0) {
            for (HeaderVo headerVo : lists) {
                headerManager.add(new Header(headerVo.getKey(), headerVo.getValue()));
            }
        }
        return headerManager;
    }

    private HTTPArgument createHTTPArgument(List<DataVo> lists) {
        HTTPArgument httpArgument = new HTTPArgument();
        HashMap hashMap = caseService.convertValue(lists);
        String jsonStr = JSONObject.toJSONString(hashMap);
        httpArgument.setValue(jsonStr);
        return httpArgument;
    }

    private HTTPSampler createHTTPSampler(String apiUrl, String apiMethod) throws MalformedURLException {
        URL url = new URL(apiUrl);
        HTTPSampler httpSampler = new HTTPSampler();
        httpSampler.setDomain(url.getHost());
        httpSampler.setPort(url.getPort());
        httpSampler.setPath(url.getPath());
        httpSampler.setMethod(apiMethod);
        httpSampler.setName("HTTP请求");
        httpSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
        httpSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
        return httpSampler;
    }

    private ResultCollector createResultCollector(Summariser summariser, int type, String apiName) {
        ResultCollector resultCollector = new ResultCollector(summariser);
        if (type == 1) {
            resultCollector.setName("汇总报告");
            resultCollector.setProperty(TestElement.TEST_CLASS,ResultCollector.class.getName());
            resultCollector.setProperty(TestElement.GUI_CLASS, SummaryReport.class.getName());
            resultCollector.setFilename(jmeterFile + apiName +".jtl");
            return resultCollector;
        }else if (type == 2) {
            resultCollector.setName("响应时间图");
            resultCollector.setProperty(TestElement.TEST_CLASS,ResultCollector.class.getName());
            resultCollector.setProperty(TestElement.GUI_CLASS, RespTimeGraphVisualizer.class.getName());
            resultCollector.setFilename(jmeterFile + apiName +".jtl");
        }else if (type == 3) {
            resultCollector.setName("察看结果树");
            resultCollector.setProperty(TestElement.TEST_CLASS,ResultCollector.class.getName());
            resultCollector.setProperty(TestElement.GUI_CLASS, ViewResultsFullVisualizer.class.getName());
            resultCollector.setFilename(jmeterFile + apiName +".jtl");
        }
        return resultCollector;
    }

    private ResponseAssertion createResponseAssertion(String testString) {
        if (null == testString) {
            testString="";
        }
        ResponseAssertion responseAssertion =  new ResponseAssertion();
        responseAssertion.setName("响应断言");
        responseAssertion.setAssumeSuccess(false);
        responseAssertion.addTestString(testString);
        responseAssertion.setToContainsType();
        responseAssertion.setTestFieldResponseData();
        responseAssertion.setProperty(TestElement.TEST_CLASS,ResponseAssertion.class.getName());
        responseAssertion.setProperty(TestElement.GUI_CLASS, AssertionGui.class.getName());
        return responseAssertion;
    }

    public RespBean runScript(Object obj, ApiVo api) throws IOException {
        //查询API信息
        String jmeterPath = obj.toString();
        //创建总结报告
        Summariser summariser = new Summariser();
        //创建结果收集器
        ResultCollector resultCollector = new ResultCollector(summariser);
        resultCollector.setName("汇总报告");
        resultCollector.setProperty(TestElement.TEST_CLASS,ResultCollector.class.getName());
        resultCollector.setProperty(TestElement.GUI_CLASS, SummaryReport.class.getName());
        resultCollector.setFilename(jmeterFile + api.getName() +".jtl");
        HashTree jmxTree = SaveService.loadTree(new File(jmeterPath));
        jmxTree.add(jmxTree.getArray()[0],resultCollector);
        //创建一个 JMeter 引擎:
        StandardJMeterEngine jmeterEngine = new StandardJMeterEngine();
        //将测试计划设置到引擎中:
        jmeterEngine.configure(jmxTree);
        //启动引擎
        jmeterEngine.run();
        return RespBean.ok("执行成功");
    }
}

  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值