import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Objects;
import java.util.Set;
import com.thoughtworks.xstream.XStream;
import org.apache.jmeter.JMeter;
import org.apache.jmeter.config.Argument;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.control.LoopController;
import org.apache.jmeter.control.gui.LoopControlPanel;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.protocol.http.control.HeaderManager;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
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.ThreadGroup;
import org.apache.jmeter.threads.gui.ThreadGroupGui;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.ListedHashTree;
import java.util.Set;
import java.util.AbstractMap;
import java.util.function.Supplier;
public class TestPlanLauncher {
public static void main(String[] args) {
// jemter 引擎
StandardJMeterEngine standardJMeterEngine = new StandardJMeterEngine();
// 设置不适用gui的方式调用jmeter
System.setProperty(JMeter.JMETER_NON_GUI, "true");
// 设置jmeter.properties文件,我们将jmeter文件存放在resources中,通过classload
String path = Objects.requireNonNull(TestPlanLauncher.class.getClassLoader().getResource("jmeter/bin/jmeter.properties")).getPath();
File jmeterPropertiesFile = new File(path);
if (jmeterPropertiesFile.exists()) {
JMeterUtils.loadJMeterProperties(jmeterPropertiesFile.getPath());
HashTree testPlanTree = new ListedHashTree();
// 创建测试计划
TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
// 创建http请求收集器
HTTPSamplerProxy examplecomSampler = createHTTPSamplerProxy();
// 创建循环控制器
LoopController loopController = createLoopController();
// 创建线程组
ThreadGroup threadGroup = createThreadGroup();
// 线程组设置循环控制
threadGroup.setSamplerController(loopController);
// 将测试计划添加到测试配置树中
HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
// 将http请求采样器添加到线程组下
threadGroupHashTree.add(examplecomSampler);
// 将生成的测试计划保存为JMeter的.jmx文件格式
try {
SaveService.saveTree(testPlanTree, new FileOutputStream("D:\\Files\\jmeter\\query.jmx"));
} catch (IOException e) {
throw new RuntimeException(e);
}
//增加结果收集
Summariser summer = null;
String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
if (!summariserName.isEmpty()) {
summer = new Summariser(summariserName);
}
String reportFile = "report\\report.jtl";
String csvFile = "report\\report.csv";
ResultCollector logger = new ResultCollector(summer);
logger.setFilename(reportFile);
ResultCollector csvlogger = new ResultCollector(summer);
csvlogger.setFilename(csvFile);
testPlanTree.add(testPlanTree.getArray()[0], logger);
testPlanTree.add(testPlanTree.getArray()[0], csvlogger);
// 配置jmeter
standardJMeterEngine.configure(testPlanTree);
// 运行
standardJMeterEngine.run();
System.exit(0);
}
}
/**
* 创建线程组
*
* @return
*/
/**
* 创建一个新的线程组对象
* 设置线程组的名称为"Example Thread Group"
* 设置线程组的初始线程数为1
* 设置线程组的 Ramp-up 时间为0
* 设置线程组的测试类为ThreadGroup.class.getName()
* 设置线程组使用调度器为true
* 设置线程组的持续时间为60
* 设置线程组的延迟时间为0
* 返回创建的线程组对象
*/
public static ThreadGroup createThreadGroup() {
ThreadGroup threadGroup = new ThreadGroup();
threadGroup.setName("Example Thread Group");
threadGroup.setNumThreads(1);
threadGroup.setRampUp(0);
threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
threadGroup.setScheduler(true);
threadGroup.setDuration(60);
threadGroup.setDelay(0);
return threadGroup;
}
/**
* 创建循环控制器
*
* @return
*/
/**
* 创建一个循环控制器
*
* @return 循环控制器
*/
public static LoopController createLoopController() {
// 创建一个循环控制器
LoopController loopController = new LoopController();
// 设置循环次数为1
loopController.setLoops(1);
// 设置循环继续执行
loopController.setFirst(true);
loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
// 初始化控制器
loopController.initialize();
// 返回创建的循环控制器
return loopController;
}
/**
* 创建http采样器
*
* @return
*/
public static HTTPSamplerProxy createHTTPSamplerProxy() {
HeaderManager headerManager = new HeaderManager();
headerManager.setProperty("Content-Type", "application/json");
HTTPSamplerProxy httpSamplerProxy = new HTTPSamplerProxy();
httpSamplerProxy.setDomain("XXX.com");
httpSamplerProxy.setPort(80);
httpSamplerProxy.setPath("/writeRelationQuery");
httpSamplerProxy.setMethod("POST");
httpSamplerProxy.setConnectTimeout("5000");
httpSamplerProxy.setUseKeepAlive(true);
httpSamplerProxy.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
httpSamplerProxy.setHeaderManager(headerManager);
httpSamplerProxy.setArguments(createArguments());
return httpSamplerProxy;
}
public static Arguments createArguments() {
Arguments arguments = new Arguments();
arguments.setName("");
arguments.addArgument(createArgument());
return arguments;
}
public static Argument createArgument() {
Argument argument = new Argument();
argument.setValue("{\"systemCode\":\"XX\",\"billCode\":XX}");
argument.setMetaData("=");
return argument;
}
}
在java项目中调用jmeter api进行接口测试的时候,上面代码执行到第65行:SaveService.saveTree(testPlanTree, new FileOutputStream("D:\Files\jmeter\query.jmx")); 保存编写的测试计划的时候报错了。错误信息如下,这个要怎么解决啊:
Exception in thread "main" com.thoughtworks.xstream.converters.ConversionException: No converter available
---- Debugging information ----
message : No converter available
type : java.util.IdentityHashMap
converter : com.thoughtworks.xstream.converters.reflection.SerializableConverter
message[1] : Unable to make private void java.util.IdentityHashMap.readObject(java.io.ObjectInputStream) throws java.io.IOException,java.lang.ClassNotFoundException accessible: module java.base does not "opens java.util" to unnamed module @1a75e76a
converter[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
message[2] : Unable to make field transient java.util.Set java.util.AbstractMap.keySet accessible: module java.base does not "opens java.util" to unnamed module @1a75e76a