性能工具之JMeter两个Java API Demo

时间:2021-07-26 01:18:47

性能工具之JMeter两个Java API Demo

概述

本文演示两个通过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


    本文源码:

    https://github.com/7DGroup/JMeter-API-Demo