引言
之前介绍过怎么通过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("执行成功");
}
}