概述
本文演示两个通过Java API执行JMeter脚本的示例
主要功能
- 在线生成jmx脚本(demo1)
- 加载本地已有 jmx 脚本(demo2)
- 运行多个 Sampler
- 将生成的 TestPlan 存储为. jmx 文件
- 执行单机压测
- 将测试执行结果存储为 .jtl or .csv 文件
示例
Maven配置
为了开始使用 JMeter API,我们首先需要将它添加到我们的 pom.xml
1. <dependencies>
2. <dependency>
3. <groupId>org.apache.jmeter</groupId>
4. <artifactId>ApacheJMeter_java</artifactId>
5. <version>4.0</version>
6. </dependency>
7. <dependency>
8. <groupId>org.apache.jmeter</groupId>
9. <artifactId>ApacheJMeter_http</artifactId>
10. <version>4.0</version>
11. </dependency>
12. </dependencies>
在线生成jmx脚本(demo1)
1. /**
2. * 代码生成测试脚本,及JMX文件Demo
3. * 1)先定义每个组件的生成方式,然后再按一定结构组装各个组件,最后生成JMX文件
4. * 2)生成.jtl结果文件
5. * 2)单机压测
6. */
7.
8. public class JMeterDemo1 {
9.
10. public static void main(String[] argv) throws Exception {
11.
12. // 设置jmeterHome路径
13. // 主要是读取了几个配置文件,jmeter.properties,user.properties,system.properties。
14. // 设置一下的本地的Locale环境。
15. // 其实到这里,是可以仅将这3个配置文件抽离出来,即不需要整个Jmeter的home目录,仅要这3个配置文件就能运行Jmeter脚本。
16. // 甚至仅在代码中写要的配置,都不需要实体的配置文件即可。
17. // 当然随着功能越来越多,平台跟Jmeter的耦合也越来越多,这个Jmeter_home目录还是越来越必要了。
18. String jmeterHome1 = "/Users/apple/Downloads/performance/apache-jmeter-4.0";
19. //File jmeterHome = new File(System.getProperty("jmeter.home"));
20. File jmeterHome = new File(jmeterHome1);
21. // 分隔符
22. String slash = System.getProperty("file.separator");
23.
24. //判断jmeterHome
25. if (jmeterHome.exists()) {
26. File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
27. if (jmeterProperties.exists()) {
28.
29. // 初始化压测引擎
30. StandardJMeterEngine jmeter = new StandardJMeterEngine();
31.
32. // JMeter初始化(属性、日志级别、区域设置等)
33. JMeterUtils.setJMeterHome(jmeterHome.getPath());
34. JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
35. // 可以注释这一行,查看额外的日志,例如DEBUG级别
36. JMeterUtils.initLogging();
37. JMeterUtils.initLocale();
38.
39. // JMeter测试计划,基本上是JOrphan HashTree
40. HashTree testPlanTree = new HashTree();
41.
42. // 第一个 HTTP Sampler - 打开 baidu.com
43. HTTPSamplerProxy baiducomSampler = new HTTPSamplerProxy();
44. baiducomSampler.setDomain("baidu.com");
45. baiducomSampler.setPort(80);
46. baiducomSampler.setPath("/");
47. baiducomSampler.setMethod("GET");
48. baiducomSampler.setName("Open baidu.com");
49. baiducomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
50. baiducomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
51.
52. // 第二个 HTTP Sampler - 打开 qq.com
53. HTTPSamplerProxy qqcomSampler = new HTTPSamplerProxy();
54. qqcomSampler.setDomain("qq.com");
55. qqcomSampler.setPort(80);
56. qqcomSampler.setPath("/");
57. qqcomSampler.setMethod("GET");
58. qqcomSampler.setName("Open qq.com");
59. qqcomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
60. qqcomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
61.
62. // Loop Controller 循环控制
63. LoopController loopController = new LoopController();
64. loopController.setLoops(1);
65. loopController.setFirst(true);
66. loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
67. loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
68. loopController.initialize();
69.
70. // Thread Group 线程组
71. ThreadGroup threadGroup = new ThreadGroup();
72. threadGroup.setName("Example Thread Group");
73. threadGroup.setNumThreads(1);
74. threadGroup.setRampUp(1);
75. threadGroup.setSamplerController(loopController);
76. threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
77. threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
78.
79. // Test Plan 测试计划
80. TestPlan testPlan = new TestPlan("创建JMeter脚本");
81. testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
82. testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
83. testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());
84.
85. // 从以上初始化的元素构造测试计划
86. testPlanTree.add(testPlan);
87. HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
88. threadGroupHashTree.add(baiducomSampler);
89. threadGroupHashTree.add(qqcomSampler);
90.
91. // 将生成的测试计划保存为JMeter的.jmx文件格式
92. SaveService.saveTree(testPlanTree, new FileOutputStream(jmeterHome + slash + "example.jmx"));
93.
94. // 在stdout中添加summary输出,得到测试进度,如:
95. // summary = 2 in 1.3s = 1.5/s Avg: 631 Min: 290 Max: 973 Err: 0 (0.00%)
96. Summariser summer = null;
97. String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
98. if (summariserName.length() > 0) {
99. summer = new Summariser(summariserName);
100. }
101.
102. // 将执行结果存储到.jtl文件中
103. String logFile = jmeterHome + slash + "example.jtl";
104. ResultCollector logger = new ResultCollector(summer);
105. logger.setFilename(logFile);
106. testPlanTree.add(testPlanTree.getArray()[0], logger);
107.
108.
109. // 单机执行测试计划
110. jmeter.configure(testPlanTree); // 设置回调监听器,并添加状态
111. jmeter.run();
112.
113. System.out.println("生成结果文件:" + jmeterHome + slash + "example.jtl");
114. System.out.println("Jmx脚本文件:" + jmeterHome + slash + "example.jmx");
115. System.exit(0);
116. }
117. }
118.
119. System.err.println("jmeter.home 未设置或指向不正确的位置");
120. System.exit(1);
121. }
122. }
运行结果:
1. summary + 1 in 00:00:04 = 0.2/s Avg: 1728 Min: 1728 Max: 1728 Err: 0 (0.00%) Active: 1 Started: 1 Finished: 0
2. summary + 1 in 00:00:01 = 1.9/s Avg: 514 Min: 514 Max: 514 Err: 0 (0.00%) Active: 0 Started: 1 Finished: 1
3. summary = 2 in 00:00:05 = 0.4/s Avg: 1121 Min: 514 Max: 1728 Err: 0 (0.00%)
4. 生成结果文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jtl
5. Jmx脚本文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jmx
6.
7. Process finished with exit code 0
加载本地jmx脚本(demo2)
1. /**
2. * 上传现成脚本demo
3. * 1)加载本地JMX文件并解析
4. * 2)生成.csv格式结果
5. * * */
6.
7. public class JMeterDemo2 {
8.
9. public static void main(String[] argv) throws Exception {
10. // 设置jmeterHome路径
11. String jmeterHome1 = "/Users/apple/Downloads/performance/apache-jmeter-4.0";
12. //File jmeterHome = new File(System.getProperty("jmeter.home"));
13. File jmeterHome = new File(jmeterHome1);
14. File jmxFile = new File(jmeterHome1 + "/example.jmx");
15.
16. // 分隔符
17. String slash = System.getProperty("file.separator");
18.
19. // 判断jmeterHome
20. if (jmeterHome.exists()) {
21. File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
22. if (jmeterProperties.exists()) {
23.
24. // 初始化压测引擎
25. StandardJMeterEngine jmeter = new StandardJMeterEngine();
26.
27. // JMeter初始化(属性、日志级别、区域设置等)
28. JMeterUtils.setJMeterHome(jmeterHome.getPath());
29. JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
30. // 可以注释这一行,查看额外的日志,例如DEBUG级别
31. JMeterUtils.initLogging();
32. JMeterUtils.initLocale();
33.
34. // JMeter测试计划,基本上是JOrphan HashTree
35. HashTree testPlanTree = new HashTree();
36.
37. // 设置jmx脚本文件的工作目录,可以根据这个来找到参数化文件及实现其文件流。
38. FileServer.getFileServer().setBaseForScript(jmxFile);
39.
40. // 加载jmx脚本,本身这个操作非常复杂。
41. // jmx脚本中通常会包含参数化文件,用户自定义的参数化,Jmeter自定义函数,各种Sampler的实现,断言,甚至用户自定义的插件等等。
42. // 同时还有各种监听接口的初始化。
43. // 这些都是要找到实现类加载的,源码中包含非常多的实现类。
44. testPlanTree = SaveService.loadTree(jmxFile);
45.
46. // 去掉没用的节点元素,替换掉可以替换的控制器,这个是递归实现的,比较复杂
47. JMeter.convertSubTree(testPlanTree);
48.
49. // 在stdout中添加summary输出,得到测试进度,如:
50. // summary = 2 in 1.3s = 1.5/s Avg: 631 Min: 290 Max: 973 Err: 0 (0.00%)
51. Summariser summer = null;
52. String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
53. if (summariserName.length() > 0) {
54. summer = new Summariser(summariserName);
55. }
56.
57. // 将执行结果存储到.csv文件中
58. String logFile = jmeterHome + slash + "example.csv";
59. ResultCollector logger = new ResultCollector(summer);
60. logger.setFilename(logFile);
61. testPlanTree.add(testPlanTree.getArray()[0], logger);
62.
63. // 单机执行测试计划
64. jmeter.configure(testPlanTree); // 设置回调监听器,并添加状态
65. jmeter.run();
66.
67. System.out.println("生成结果文件:" + jmeterHome + slash + "example.csv");
68. System.out.println("加载Jmx脚本文件:" + jmeterHome + slash + "example.jmx");
69. System.exit(0);
70. }
71. }
72. System.err.println("jmeter.home 未设置或指向不正确的位置");
73. System.exit(1);
74. }
75. }
运行结果:
1. summary + 1 in 00:00:04 = 0.3/s Avg: 1426 Min: 1426 Max: 1426 Err: 0 (0.00%) Active: 1 Started: 1 Finished: 0
2. summary + 1 in 00:00:00 = 3.0/s Avg: 281 Min: 281 Max: 281 Err: 0 (0.00%) Active: 0 Started: 1 Finished: 1
3. summary = 2 in 00:00:04 = 0.5/s Avg: 853 Min: 281 Max: 1426 Err: 0 (0.00%)
4. 生成结果文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.csv
5. 加载Jmx脚本文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jmx
本文源码: