使用Java通过JMeter API生成.jmx文件失败,求可行示例
使用Java JMeter API生成可运行的JMeter脚本及非GUI运行示例
问题分析
你的代码核心问题是HashTree的层级结构错误:JMeter的测试元素是按「测试计划→线程组→逻辑控制器→采样器」的层级嵌套的,而你把所有元素平级添加到根HashTree,导致生成的.jmx结构混乱,无法正常运行。
可运行代码示例
以下是修正后的完整代码,包含脚本生成和非GUI运行的逻辑:
import org.apache.jmeter.config.Arguments; import org.apache.jmeter.config.gui.ArgumentsPanel; 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.sampler.HTTPSampler; import org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui; 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.gui.ThreadGroupGui; import org.apache.jmeter.util.JMeterUtils; import org.apache.jorphan.collections.HashTree; import java.io.FileOutputStream; import java.io.IOException; public class JMeterScriptGenerator { public static void main(String[] args) throws IOException { // 1. 初始化JMeter环境 String jmeterHome = "/path/to/your/jmeter/home"; // 替换为你的JMeter安装路径 JMeterUtils.setJMeterHome(jmeterHome); JMeterUtils.loadJMeterProperties(jmeterHome + "/bin/jmeter.properties"); JMeterUtils.initLocale(); // 2. 创建HTTP请求采样器 HTTPSampler httpSampler = new HTTPSampler(); httpSampler.setName("GET Data API"); httpSampler.setDomain("localhost"); httpSampler.setPort(5000); httpSampler.setPath("/api/v1/data"); httpSampler.setMethod("GET"); httpSampler.setProperty(TestElement.TEST_CLASS, HTTPSampler.class.getName()); httpSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName()); // 3. 创建循环控制器 LoopController loopController = new LoopController(); loopController.setName("循环控制器"); loopController.setLoops(1); loopController.setFirst(true); loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName()); loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName()); // 4. 创建线程组 SetupThreadGroup threadGroup = new SetupThreadGroup(); threadGroup.setName("前置线程组"); threadGroup.setNumThreads(1); threadGroup.setRampUp(1); threadGroup.setSamplerController(loopController); threadGroup.setProperty(TestElement.TEST_CLASS, SetupThreadGroup.class.getName()); threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName()); // 5. 创建测试计划 TestPlan testPlan = new TestPlan("MY TEST PLAN"); testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName()); testPlan.setProperty(TestElement.GUI_CLASS, ArgumentsPanel.class.getName()); testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement()); // 6. 构建正确的HashTree层级结构 HashTree testPlanTree = new HashTree(); HashTree threadGroupTree = testPlanTree.add(testPlan, threadGroup); HashTree loopTree = threadGroupTree.add(loopController); loopTree.add(httpSampler); // 7. 保存为.jmx文件 String jmxFilePath = "jmxFile.jmx"; SaveService.saveTree(testPlanTree, new FileOutputStream(jmxFilePath)); System.out.println("JMeter脚本已生成:" + jmxFilePath); // 8. 非GUI模式运行脚本 runJmxInNonGuiMode(jmxFilePath); } private static void runJmxInNonGuiMode(String jmxFilePath) { StandardJMeterEngine jmeterEngine = new StandardJMeterEngine(); JMeterUtils.loadJMeterProperties(JMeterUtils.getJMeterHome() + "/bin/jmeter.properties"); try { HashTree testTree = SaveService.loadTree(new java.io.File(jmxFilePath)); jmeterEngine.configure(testTree); jmeterEngine.run(); System.out.println("脚本执行完成"); } catch (Exception e) { e.printStackTrace(); } } }
关键修正点
- 层级结构:严格按照「测试计划→线程组→循环控制器→HTTP采样器」的嵌套关系构建HashTree,每个父元素的子元素通过
add方法的返回HashTree添加 - GUI类属性:给每个测试元素设置
GUI_CLASS属性,确保生成的.jmx能在JMeter GUI中正常打开 - 环境初始化:补充设置JMeter Home路径,确保JMeter能加载必要的配置和依赖
- 非GUI运行逻辑:新增
runJmxInNonGuiMode方法,直接通过API启动测试运行
依赖说明
确保你的项目中添加了JMeter的核心依赖(以Maven为例):
<dependencies> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_core</artifactId> <version>5.6.3</version> <!-- 使用对应版本 --> </dependency> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_http</artifactId> <version>5.6.3</version> </dependency> </dependencies>
内容的提问来源于stack exchange,提问作者Akhil Vasudevan
相关产品推荐
相关产品推荐

