性能测试学习之Jmeter扩展组件开发实战(八)

1,470 阅读8分钟

小时候发誓长大以后要踏着七彩祥云去迎娶我的公主,没想长大了买个电驴还是按揭的

学会JavaSamplerClient、AbstractJavaSamplerClient两种实现方式,并掌握每一个方法的生命周期。使用java语言进行扩展组件开发,掌握开发思路,能够进行自主开发。

7.1 扩展组件开发的意义

Jemter提供的不能满足一些特殊的要求

  • 定制化开发组件
    • 入参
    • 协议
    • 复杂调用逻辑
    • 功能
    • 等等等等。。。

7.2 开发前的工具准备

  • 下载JAVA
  • 下载IDEA

www.jetbrains.com/

  • 安装自行百度

7.3 创建maven工程及可能遇到的问题

扩展开发实现的两种方式

  • 继承AbstractJavaSamplerClient抽象类
  • 实现JavaSamplerClient接口

实践Hello JMeter

创建工程目录,我选择了Maven这个框架,容易打包,普通的也可以

  • 项目project文件

平时我们用jar包的话需要从网上下载下来,导进去才可以使用,在这里直接引用即可

编写信息下载包,下载完后没有红色字体,表示安装完毕

  • 下载失败 删除目录下的文件 C:\Users\x1c.m2\repository\org\apache\jmeter\ApacheJMeter_java

百度搜索:jmeter maven jar 可参考如何写: mvnrepository.com/artifact/or…

<!-- https://mvnrepository.com/artifact/org.apache.jmeter/ApacheJMeter_core -->
<dependency>
    <groupId>org.apache.jmeter</groupId>
    <artifactId>ApacheJMeter_core</artifactId>
    <version>3.1</version>
</dependency>

第一扩展开发demo的实现

打包,这里可能报错,mvn找不到,下载一下安装设置环境变量就可以了

package com.demo;

import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

public class First extends AbstractJavaSamplerClient {

    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
        System.out.println("hello Jmeter~~~~");
        return null;
    }
}

  • 打开Jmeter路径

\apache-jmeter-3.1\lib\ext

  • 挪动工程编译后自己jar包

  • 启动Jmeter运行

实现方法的讲解

  • 创建Java类 Second
package com.demo;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

public class Second implements JavaSamplerClient {
    /**
     * 初始化方法,所有初始化动作都可以在这里写
     * @param javaSamplerContext
     */
    public void setupTest(JavaSamplerContext javaSamplerContext) {
        System.out.println("setupTest run");
    }

    /**
     * 实现你具体功能逻辑的方法
     * @param javaSamplerContext
     * @return
     */
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {

        System.out.println("runTest run");
        return null;
    }

    /**
     * 做一些收尾工作
     * @param javaSamplerContext
     */
    public void teardownTest(JavaSamplerContext javaSamplerContext) {
        System.out.println("teardownTest run");
    }

    /**
     * 这个方法决定了再jmeter当中要显示那些属性
     * @return
     */
    public Arguments getDefaultParameters() {
        System.out.println("getDefaultParameters run");
        return null;
    }
}

打包:mvn clean package

  • 移动编译后的文件到jmeter目录中

  • 运行Jmeter

未运行显示

运行后显示

自定义参数的实现getDefaultParameters

访问百度

package com.demo;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

public class Second implements JavaSamplerClient {

    //URLNAME 就是图形化界面当中显示的变量名称
    private static final String URLNAME = "URL";

    //设置界面当中默认显示变量的值
    private static final String DEFAULTURL = "https://www.baidu.com";
    /**
     * 这个方法决定了再jmeter当中要显示那些属性
     * @return arguments
     */
    public Arguments getDefaultParameters() {
        System.out.println("getDefaultParameters run");
        Arguments arguments = new Arguments();
        arguments.addArgument(URLNAME,DEFAULTURL);

        return arguments;
    }


    /**
     * 初始化方法,所有初始化动作都可以在这里写
     * @param javaSamplerContext
     */
    public void setupTest(JavaSamplerContext javaSamplerContext) {
        System.out.println("setupTest run");
    }

    /**
     * 实现你具体功能逻辑的方法
     * @param javaSamplerContext
     * @return
     */
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {

        System.out.println("runTest run");
        return null;
    }

    /**
     * 做一些收尾工作
     * @param javaSamplerContext
     */
    public void teardownTest(JavaSamplerContext javaSamplerContext) {
        System.out.println("teardownTest run");
    }


}
  • 编译

mvn clean package

  • 替换

  • 重启jmeter打开

默认加载

初始化方法的作用与实现setupTest

package com.demo;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

import java.net.URL;

public class Second implements JavaSamplerClient {

    //URLNAME 就是图形化界面当中显示的变量名称
    private static final String URLNAME = "URL";

    //设置界面当中默认显示变量的值
    private static final String DEFAULTURL = "https://www.baidu.com";
    /**
     * 这个方法决定了再jmeter当中要显示那些属性
     * @return arguments
     */
    public Arguments getDefaultParameters() {
        System.out.println("getDefaultParameters run");
        Arguments arguments = new Arguments();
        arguments.addArgument(URLNAME,DEFAULTURL);

        return arguments;
    }

    private String inputUrl;

    /**
     * 初始化方法,所有初始化动作都可以在这里写
     * @param javaSamplerContext
     */
    public void setupTest(JavaSamplerContext javaSamplerContext) {
        inputUrl = javaSamplerContext.getParameter(URLNAME,DEFAULTURL);
        System.out.println("setupTest run");
        System.out.println("用户输入的url地址是:"+inputUrl);
    }

    /**
     * 实现你具体功能逻辑的方法
     * @param javaSamplerContext
     * @return
     */
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {

        System.out.println("runTest run");
        return null;
    }

    /**
     * 做一些收尾工作
     * @param javaSamplerContext
     */
    public void teardownTest(JavaSamplerContext javaSamplerContext) {
        System.out.println("teardownTest run");
    }


}
  • 打包,替换,重启Jmeter

  • 运行

如何将响应数据显示到查看结果树中

我们定义我们自己的结果树,SampleResult方法

package com.demo;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

import java.net.URL;

public class Second implements JavaSamplerClient {

    //URLNAME 就是图形化界面当中显示的变量名称
    private static final String URLNAME = "URL";

    //设置界面当中默认显示变量的值
    private static final String DEFAULTURL = "https://www.baidu.com";
    /**
     * 这个方法决定了再jmeter当中要显示那些属性
     * @return arguments
     */

    //用来存储响应的数据,目的是将响应结果放到察看结果树当中
    public String resultData;

    public Arguments getDefaultParameters() {
        System.out.println("getDefaultParameters run");
        Arguments arguments = new Arguments();
        arguments.addArgument(URLNAME,DEFAULTURL);

        return arguments;
    }

    private String inputUrl;

    /**
     * 初始化方法,所有初始化动作都可以在这里写
     * @param javaSamplerContext
     */
    public void setupTest(JavaSamplerContext javaSamplerContext) {
        inputUrl = javaSamplerContext.getParameter(URLNAME,DEFAULTURL);
        System.out.println("setupTest run");
        System.out.println("用户输入的url地址是:"+inputUrl);
    }

    /**
     * 实现你具体功能逻辑的方法
     * @param javaSamplerContext
     * @return
     */
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
        SampleResult result= new SampleResult();
        System.out.println("runTest run");
        resultData = "这就是响应结果";
        result.setResponseData(resultData, null);
        result.setDataType(SampleResult.TEXT);
        return result;
    }

    /**
     * 做一些收尾工作
     * @param javaSamplerContext
     */
    public void teardownTest(JavaSamplerContext javaSamplerContext) {
        System.out.println("teardownTest run");
    }


}
  • 打包,替换,重启Jmeter

package com.demo;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

import java.net.URL;

public class Second implements JavaSamplerClient {

    //URLNAME 就是图形化界面当中显示的变量名称
    private static final String URLNAME = "URL";

    //设置界面当中默认显示变量的值
    private static final String DEFAULTURL = "https://www.baidu.com";
    /**
     * 这个方法决定了再jmeter当中要显示那些属性
     * @return arguments
     */

    //用来存储响应的数据,目的是将响应结果放到察看结果树当中
    public String resultData;

    public Arguments getDefaultParameters() {
        System.out.println("getDefaultParameters run");
        Arguments arguments = new Arguments();
        arguments.addArgument(URLNAME,DEFAULTURL);

        return arguments;
    }

    private String inputUrl;

    /**
     * 初始化方法,所有初始化动作都可以在这里写
     * @param javaSamplerContext
     */
    public void setupTest(JavaSamplerContext javaSamplerContext) {
        inputUrl = javaSamplerContext.getParameter(URLNAME,DEFAULTURL);
        System.out.println("setupTest run");
        System.out.println("用户输入的url地址是:"+inputUrl);
    }

    /**
     * 实现你具体功能逻辑的方法
     * @param javaSamplerContext
     * @return
     */
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
        SampleResult result= new SampleResult();
        System.out.println("runTest run");
        resultData = "这就是响应结果";
        //告诉查看结果树是否成功
        result.setSuccessful(true);
        result.setResponseData(resultData, null);
        result.setDataType(SampleResult.TEXT);
        return result;
    }

    /**
     * 做一些收尾工作
     * @param javaSamplerContext
     */
    public void teardownTest(JavaSamplerContext javaSamplerContext) {
        System.out.println("teardownTest run");
    }


}

这样解决了Jmeter报红

  • 修改名称

在Java中设置

自定义java请求的开发

package com.demo;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class Second implements JavaSamplerClient {

    //URLNAME 就是图形化界面当中显示的变量名称
    private static final String URLNAME = "URL";

    //设置界面当中默认显示变量的值
    private static final String DEFAULTURL = "https://www.baidu.com";
    /**
     * 这个方法决定了再jmeter当中要显示那些属性
     * @return arguments
     */

    //用来存储响应的数据,目的是将响应结果放到察看结果树当中
    public String resultData;

    public Arguments getDefaultParameters() {
        System.out.println("getDefaultParameters run");
        Arguments arguments = new Arguments();
        arguments.addArgument(URLNAME,DEFAULTURL);

        return arguments;
    }

    private String inputUrl;

    /**
     * 初始化方法,所有初始化动作都可以在这里写
     * @param javaSamplerContext
     */
    public void setupTest(JavaSamplerContext javaSamplerContext) {
        inputUrl = javaSamplerContext.getParameter(URLNAME,DEFAULTURL);
        System.out.println("setupTest run");
        System.out.println("用户输入的url地址是:"+inputUrl);
    }

    /**
     * 实现你具体功能逻辑的方法
     * @param javaSamplerContext
     * @return
     */
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
        SampleResult result= new SampleResult();
        System.out.println("runTest run");
        StringBuffer sb = new StringBuffer();

        try {
            URL url = new URL(inputUrl);

            URLConnection conn = url.openConnection();

            byte[] buffer = new byte[1024];
            int len;

            result.sampleStart();//标记事务的开始
            InputStream in = conn.getInputStream();
            while ((len=in.read(buffer))!=-1){
                resultData = new String(buffer, "UTF-8");
                sb.append(resultData);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


       // resultData = "这就是响应结果";
        resultData = sb.toString();
        result.setSampleLabel("caichen JAVA URL request");
        //告诉查看结果树是否成功
        result.setSuccessful(true);
        result.setResponseData(resultData, null);
        result.setDataType(SampleResult.TEXT);
        return result;
    }

    /**
     * 做一些收尾工作
     * @param javaSamplerContext
     */
    public void teardownTest(JavaSamplerContext javaSamplerContext) {
        System.out.println("teardownTest run");
    }


}
  • 打包,替换jar,重启Jmeter

try中一般是编写业务逻辑代码

函数助手扩展开发demo演示

  • 添加引入
    如果不下载在右侧栏点击刷新按钮
  • 创建包,包名必须是functions不然函数助手识别不出来

package com.functions;

import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.functions.AbstractFunction;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;

import java.util.Collection;
import java.util.List;

public class Caichen extends AbstractFunction {

    /**
     * 执行方法
     * @param sampleResult
     * @param sampler
     * @return
     * @throws InvalidVariableException
     */
    public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {
        System.out.println("execute run~~~");
        return null;
    }

    /**
     * 设置参数,接收用户传递的参数
     * @param collection
     * @throws InvalidVariableException
     */
    public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException {
        System.out.println("setParameters run");
    }


    /**
     * 功能名称
     * @return
     */
    public String getReferenceKey() {
        System.out.println("getReferenceKey run");
        return "__MyDemo";
    }

    /**
     * 功能描述或参数描述
     * @return
     */
    public List<String> getArgumentDesc() {
        System.out.println("getArgumentDesc run");
        return null;
    }
}

  • 打包,移动包到ext目录下,启动jmeter

解决空指针问题

解决控制台显示问题:Uncaught Exception java.lang.NullPointerException. See log file for details.

  • 验证功能

${__MyDemo(AAA)}

package com.functions;

import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.functions.AbstractFunction;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Caichen extends AbstractFunction {

    /**
     * 执行方法
     * @param sampleResult
     * @param sampler
     * @return
     * @throws InvalidVariableException
     */
    public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {
        System.out.println("execute run~~~");
        return null;
    }

    /**
     * 设置参数,接收用户传递的参数
     * @param collection
     * @throws InvalidVariableException
     */
    public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException {
        System.out.println("setParameters run");
    }


    /**
     * 功能名称
     * @return
     */
    public String getReferenceKey() {
        System.out.println("getReferenceKey run");
        return "__MyDemo";
    }

    /**
     * 功能描述或参数描述
     * @return
     */
    public List<String> getArgumentDesc() {
        System.out.println("getArgumentDesc run");
        List desc = new ArrayList();
        desc.add("two nums + ");
        return desc;
    }
}

自定义扩展函数助手的开发

实现两数相加

  • 代码实现
  • 打包,替换,重启jmeter

package com.functions;

import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.functions.AbstractFunction;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Caichen extends AbstractFunction {

    /**
     * 执行方法
     * @param sampleResult
     * @param sampler
     * @return
     * @throws InvalidVariableException
     */
    private  Object[] values;
    private  CompoundVariable first,second;//存储第一个和第二个参数

    public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {
        System.out.println("execute run~~~");

        first = (CompoundVariable) values[0];
        System.out.println("first param is:"+first);
        first = (CompoundVariable) values[1];
        System.out.println("second param is:"+second);

        int count = new Integer(first.execute().trim()) + new Integer(second.execute().trim());

        System.out.println("sum value is:"+count);
        return String.valueOf(count);
    }

    /**
     * 设置参数,接收用户传递的参数
     * @param collection
     * @throws InvalidVariableException
     */
    public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException {
        checkParameterCount(collection, 2);
        values = collection.toArray();



        System.out.println("setParameters run");
    }


    /**
     * 功能名称
     * @return
     */
    public String getReferenceKey() {
        System.out.println("getReferenceKey run");
        return "__MyDemoCaichen";
    }

    /**
     * 功能描述或参数描述
     * @return
     */
    public List<String> getArgumentDesc() {
        System.out.println("getArgumentDesc run");
        List desc = new ArrayList();
        desc.add("one num:");
        desc.add("two nums:");
        return desc;
    }
}

好了各位,以上就是这篇文章的全部内容了,能看到这里人啊,都是人才。

如果这个文章写得还不错,觉得「王采臣」我有点东西的话 求点赞👍求关注❤️求分享👥 对耿男我来说真的非常有用!!!

白嫖不好,创作不易,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

王采臣 | 文  【原创】 如果本篇博客有任何错误,请批评指教,不胜感激 ! 微信公众号:

又到半夜了,好累晚安~