性能工具之JMeter两个Java API Demo

文章目录

概述

本文演示了通过Java API执行JMeter脚本的示例

主要功能

  • 在线生成jmx脚本(demo1)
  • 加载本地已有jmx脚本(demo2)
  • 运行多个Sampler
  • 将生成的JMeter测试存储为.jmx文件
  • 执行单机压测
  • 将测试执行结果存储为.jtl or .csv文件

示例

Maven配置

为了开始使用 JMeter API,我们首先需要将它添加到我们的 pom.xml

<dependencies>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_java</artifactId>
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_http</artifactId>
            <version>4.0</version>
        </dependency>
    </dependencies>

在线生成jmx脚本(demo1)

/**
 * 代码生成测试脚本,及JMX文件Demo
 * 1)先定义每个组件的生成方式,然后再按一定结构组装各个组件,最后生成JMX文件
 * 2)生成.jtl结果文件
 * 2)单机压测
 */

public class JMeterDemo1 {

    public static void main(String[] argv) throws Exception {

    	// 设置jmeterHome路径
		// 主要是读取了几个配置文件,jmeter.properties,user.properties,system.properties。
		// 设置一下的本地的Locale环境。
		// 其实到这里,是可以仅将这3个配置文件抽离出来,即不需要整个Jmeter的home目录,仅要这3个配置文件就能运行Jmeter脚本。
		// 甚至仅在代码中写要的配置,都不需要实体的配置文件即可。
		// 当然随着功能越来越多,平台跟Jmeter的耦合也越来越多,这个Jmeter_home目录还是越来越必要了。
		String jmeterHome1 = "/Users/apple/Downloads/performance/apache-jmeter-4.0";
        //File jmeterHome = new File(System.getProperty("jmeter.home"));
		File jmeterHome = new File(jmeterHome1);
		// 分隔符
        String slash = System.getProperty("file.separator");

        //判断jmeterHome
        if (jmeterHome.exists()) {
            File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
            if (jmeterProperties.exists()) {

				// 初始化压测引擎
                StandardJMeterEngine jmeter = new StandardJMeterEngine();

                // JMeter初始化(属性、日志级别、区域设置等)
                JMeterUtils.setJMeterHome(jmeterHome.getPath());
                JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
                // 可以注释这一行,查看额外的日志,例如DEBUG级别
                JMeterUtils.initLogging();
                JMeterUtils.initLocale();

                // JMeter测试计划,基本上是JOrphan HashTree
                HashTree testPlanTree = new HashTree();

                // 第一个 HTTP Sampler - 打开 baidu.com
                HTTPSamplerProxy baiducomSampler = new HTTPSamplerProxy();
				baiducomSampler.setDomain("baidu.com");
				baiducomSampler.setPort(80);
				baiducomSampler.setPath("/");
				baiducomSampler.setMethod("GET");
				baiducomSampler.setName("Open baidu.com");
				baiducomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
				baiducomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());

                // 第二个 HTTP Sampler - 打开 qq.com
                HTTPSamplerProxy qqcomSampler = new HTTPSamplerProxy();
				qqcomSampler.setDomain("qq.com");
				qqcomSampler.setPort(80);
				qqcomSampler.setPath("/");
				qqcomSampler.setMethod("GET");
				qqcomSampler.setName("Open qq.com");
				qqcomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
				qqcomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());

                // Loop Controller 循环控制
                LoopController loopController = new LoopController();
                loopController.setLoops(1);
                loopController.setFirst(true);
                loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
                loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
                loopController.initialize();

                // Thread Group 线程组
                ThreadGroup threadGroup = new ThreadGroup();
                threadGroup.setName("Example Thread Group");
                threadGroup.setNumThreads(1);
                threadGroup.setRampUp(1);
                threadGroup.setSamplerController(loopController);
                threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
                threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());

                // Test Plan 测试计划
                TestPlan testPlan = new TestPlan("创建JMeter脚本");
                testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
                testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
                testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());

				// 从以上初始化的元素构造测试计划
                testPlanTree.add(testPlan);
                HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
                threadGroupHashTree.add(baiducomSampler);
                threadGroupHashTree.add(qqcomSampler);

				// 将生成的测试计划保存为JMeter的.jmx文件格式
                SaveService.saveTree(testPlanTree, new FileOutputStream(jmeterHome + slash + "example.jmx"));

				// 在stdout中添加summary输出,得到测试进度,如:
                // summary =      2 in   1.3s =    1.5/s Avg:   631 Min:   290 Max:   973 Err:     0 (0.00%)
                Summariser summer = null;
                String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
                if (summariserName.length() > 0) {
                    summer = new Summariser(summariserName);
                }

				// 将执行结果存储到.jtl文件中
                String logFile = jmeterHome + slash + "example.jtl";
                ResultCollector logger = new ResultCollector(summer);
                logger.setFilename(logFile);
                testPlanTree.add(testPlanTree.getArray()[0], logger);


				// 单机执行测试计划
                jmeter.configure(testPlanTree);  // 设置回调监听器,并添加状态
                jmeter.run();

                System.out.println("生成结果文件:" + jmeterHome + slash + "example.jtl");
                System.out.println("Jmx脚本文件:" + jmeterHome + slash + "example.jmx");
                System.exit(0);
            }
        }
        
        System.err.println("jmeter.home 未设置或指向不正确的位置");
        System.exit(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
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
summary =      2 in 00:00:05 =    0.4/s Avg:  1121 Min:   514 Max:  1728 Err:     0 (0.00%)
生成结果文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jtl
Jmx脚本文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jmx

Process finished with exit code 0

加载本地已有jmx脚本(demo2)

/**
 * 上传现成脚本demo
 * 1)加载已有JMX文件并解析
 * 2)生成.csv格式结果
 * * */

public class JMeterDemo2 {

    public static void main(String[] argv) throws Exception {
    	// 设置jmeterHome路径
		String jmeterHome1 = "/Users/apple/Downloads/performance/apache-jmeter-4.0";
        //File jmeterHome = new File(System.getProperty("jmeter.home"));
		File jmeterHome = new File(jmeterHome1);
		File jmxFile = new File(jmeterHome1 + "/example.jmx");

		// 分隔符
        String slash = System.getProperty("file.separator");

        // 判断jmeterHome
        if (jmeterHome.exists()) {
            File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
            if (jmeterProperties.exists()) {

            	// 初始化压测引擎
                StandardJMeterEngine jmeter = new StandardJMeterEngine();

                // JMeter初始化(属性、日志级别、区域设置等)
                JMeterUtils.setJMeterHome(jmeterHome.getPath());
                JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
                // 可以注释这一行,查看额外的日志,例如DEBUG级别
                JMeterUtils.initLogging();
                JMeterUtils.initLocale();

                // JMeter测试计划,基本上是JOrphan HashTree
                HashTree testPlanTree = new HashTree();

				// 设置jmx脚本文件的工作目录,可以根据这个来找到参数化文件及实现其文件流。
				FileServer.getFileServer().setBaseForScript(jmxFile);

				// 加载jmx脚本,本身这个操作非常复杂。
				// jmx脚本中通常会包含参数化文件,用户自定义的参数化,Jmeter自定义函数,各种Sampler的实现,断言,甚至用户自定义的插件等等。
				// 同时还有各种监听接口的初始化。
				// 这些都是要找到实现类加载的,源码中包含非常多的实现类。
				testPlanTree = SaveService.loadTree(jmxFile);

				// 去掉没用的节点元素,替换掉可以替换的控制器,这个是递归实现的,比较复杂
				JMeter.convertSubTree(testPlanTree);

				// 在stdout中添加summary输出,得到测试进度,如:
                // summary =      2 in   1.3s =    1.5/s Avg:   631 Min:   290 Max:   973 Err:     0 (0.00%)
                Summariser summer = null;
                String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
                if (summariserName.length() > 0) {
                    summer = new Summariser(summariserName);
                }

				// 将执行结果存储到.csv文件中
                String logFile = jmeterHome + slash + "example.csv";
                ResultCollector logger = new ResultCollector(summer);
                logger.setFilename(logFile);
                testPlanTree.add(testPlanTree.getArray()[0], logger);

				// 单机执行测试计划
                jmeter.configure(testPlanTree);  // 设置回调监听器,并添加状态
                jmeter.run();

                System.out.println("生成结果文件:" + jmeterHome + slash + "example.csv");
                System.out.println("加载Jmx脚本文件:" + jmeterHome + slash + "example.jmx");
                System.exit(0);
            }
        }
        System.err.println("jmeter.home 未设置或指向不正确的位置");
        System.exit(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
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
summary =      2 in 00:00:04 =    0.5/s Avg:   853 Min:   281 Max:  1426 Err:     0 (0.00%)
生成结果文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.csv
加载Jmx脚本文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jmx

本文源码:
https://github.com/zuozewei/JMeter-API-Demo

上一篇:【Java】JMX入门


下一篇:java获取资源文件