引言
之前介绍过怎么通过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 {@AutowiredApiMapper apiMapper;@AutowiredDataMapper dataMapper;@AutowiredHeaderMapper headerMapper;@AutowiredCaseService caseService;@AutowiredCaseMapper 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("执行成功");}
}