Apache JMeter 是 Apache 基于 Java 开发的开源压力测试工具,但后来扩展到了其他测试领域,像接口测试。但,随着 IT 行业的快速发展,不同企业或组织需求更加丰富,JMeter 默认的功能往往不能满足所有的需求,在一些企业里,会对这款工具进行二次开发。
使用前准备:
- JDK:Java 开发工具包,是所有 Java 开发或项目运行的基础
- IntelliJ IDEA:一个进行 Java 项目开发的集成开发环境
- JMeter:下载5.0以上版本即可,本人的是5.3版本
函数开发
JMeter 自带函数库中,提供了丰富的函数,并被广泛使用,如__Random、__UUID 等。但,不同接口测试、性能测试项目或场景中,有着不同的特性,JMeter 自带的函数并不完全满足业务需要。基于 JMeter 的自定义函数开发,就能满足各类特性业务的需求,在实际的测试中有着非常重要的应用。
自定义函数必须继承ApacheJMeter_functions.jar包(位于D:\apache-jmeter-5.3\lib\ext\目录下)中的AbstractFunction 类,并重写父类的 4 个方法。
- execute,函数执行逻辑,必需,自定义函数的核心逻辑,并返回经过处理后的内容。见如下代码:
//业务主逻辑 @Override public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException { SampleResult sampleResult1 = new SampleResult(); try { sampleResult1.sampleStart(); int index=getNum(0,telFirst.length-1); String telNum = telFirst[index]; String two = String.valueOf(getNum(1, 888) + 10000).substring(1); String three = String.valueOf(getNum(1, 9100) + 10000).substring(1); tel = telNum + two + three; if (varName != null) { JMeterVariables vars = getVariables(); final String varTrim = varName.execute().trim(); if (vars != null && varTrim.length() > 0) { vars.put(varTrim, telNum); } } sampleResult1.setResponseData("手机号区段:"+ telNum +" 随机生成的手机号是:" + tel,"utf-8"); sampleResult1.setSuccessful(true); }catch (Exception e){ sampleResult.setSuccessful(false); e.printStackTrace(); }finally { sampleResult1.sampleEnd(); } return tel; //返回函数逻辑处理后想要的值 }
- getReferenceKey,获取函数名称方法,必需,返回一个字符串,表示在 JMeter 中使用自定义函数的函数名,一般以双下划线开头,如__Operate、__IDNumber。见如下代码:
//获取函数的名称 @Override public String getReferenceKey() { return KEY;//该变量为创建类中的一个变量,完整代码见文章后半部分 }
- setParameters,设置函数接收参数值,如果自定义函数有参数,用于接收调用时传递过来的参数,注意使用时,字符串参数不要加双引号。见如下代码:
//获取参数值 @Override public void setParameters(Collection<CompoundVariable> args0) throws InvalidVariableException { //检测用户调用函数时,检测参数个数 checkParameterCount(args0,1); Object[] params = args0.toArray(); if (params.length > 0) { varName = (CompoundVariable) params[0]; } else { varName = null; } }
- getArgumentDesc,函数参数描述,如果自定义函数有参数,用于返回函数参数说明,见如下代码:
//获取界面所要显示的参数说明 @Override public List<String> getArgumentDesc() { return desc;//该变量为创建类中的一个变量,完整代码见文章后半部分 }
开发步骤
- 创建一个普通的java项目,添加jmeter安装目录下的jar包作为依赖包(D:\apache-jmeter-5.3\lib\ext\ApacheJMeter_core.jar和ApacheJMeter_functions.jar),点击【Apply】和【OK】
- 在项目的src目录下新建一个package,命名org.apache.jmeter.functions
- 在报下新建一个类(java class)文件,命名自由不违反java命名规范即可
- 该类继承 AbstractFunction 类,并覆写其 4 个方法
execute 方法:添加插件逻辑
getReferenceKey 方法:返回自定义名称函数,用于在 JMeter 中调用
setParameters 方法:获取传递的参数
getArgumentDesc:返回参数描述
注意,自定义函数(类)必须在*.functions 包下
完整代码如下:
package org.apache.jmeter.functions;
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;
import org.apache.jmeter.threads.JMeterVariables;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
public class RandomPhoneJmeterFunctions extends AbstractFunction {
private String tel;
//定义函数名称
private static final String KEY = "__RandomPhone";
//定义函数界面显示的参数名称
private static final List<String> desc = new LinkedList<String>();
static {
desc.add("界面参数");
}
private static final String[] telFirst = "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153 ".split(",");
private CompoundVariable varName;
//业务主逻辑
@Override
public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {
SampleResult sampleResult1 = new SampleResult();
try {
sampleResult1.sampleStart();
int index = getNum(0, telFirst.length - 1);
String telNum = telFirst[index];
String two = String.valueOf(getNum(1, 888) + 10000).substring(1);
String three = String.valueOf(getNum(1, 9100) + 10000).substring(1);
tel = telNum + two + three;
if (varName != null) {
JMeterVariables vars = getVariables();
final String varTrim = varName.execute().trim();
if (vars != null && varTrim.length() > 0) {
vars.put(varTrim, telNum);
}
}
sampleResult1.setResponseData("手机号区段:" + telNum + " 随机生成的手机号是:" + tel, "utf-8");
sampleResult1.setSuccessful(true);
} catch (Exception e) {
sampleResult.setSuccessful(false);
e.printStackTrace();
} finally {
sampleResult1.sampleEnd();
}
return tel;
}
//获取参数值
@Override
public void setParameters(Collection<CompoundVariable> args0) throws InvalidVariableException {
//检测用户调用函数时,检测参数个数
checkParameterCount(args0, 1);
Object[] params = args0.toArray();
if (params.length > 0) {
varName = (CompoundVariable) params[0];
} else {
varName = null;
}
}
//获取函数的名称
@Override
public String getReferenceKey() {
return KEY;
}
//获取界面所要显示的参数说明
@Override
public List<String> getArgumentDesc() {
return desc;
}
private static int getNum(int start, int end) {
return (int) (Math.random() * (end - 1));
}
}
- 打包自定义函数成jar包,鼠标右键要打包的java文件点击“Compile 'xxxxxxx.java'”(由于本人已经编译过一次所以显示Recompile),一会儿在项目中出现out主文件及相同包路径,做里层自动增加一个同名的class文件,此时编译完成;接着点击“File > Project Structure>Project Settings>Artifacts”,然后点击右上角加号,选择JAR>Empty
在窗口中Name字段输入与java文件同名的名字,在右侧展开项目模块,看见下方第一个是之前编译过的文件,选中双击即添加到左侧框中,点击【Apply】和【OK】按钮。
一会儿就发现左侧项目结构中添加了artifacts目录,说明打包元素添加成功。
- 点击IDEA菜单“Build>Build Artifacts...”
直接点击Build,开始打包,
一会儿左侧项目结构中out目录下新增artifacts目录且目录下出现打包成功的jar包。
- 将打包好的jar包文件拷贝到 JMeter 安装目录的 lib/ext 目录中,然后重新启动 JMeter,打开函数助手对话框,可以查看到自己定义的函数
- 输入一个文本参数点击生成,可以看见可以成功返回一个期望值,至此函数开发成功。