引入依赖的包
<!-- https://mvnrepository.com/artifact/org.apache.jmeter/ApacheJMeter_java -->
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>5.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.jmeter/ApacheJMeter_functions -->
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_functions</artifactId>
<version>5.3</version>
</dependency>
创建.functions包
jmeter.properties配置了自定义函数所在包名必须包含".functions"。不然生成的jar导入jmeter之后,新的函数仍然不会显示
classfinder.functions.contain=.functions.
classfinder.functions.notContain=.gui.
创建继承AbstractFunction的类
AbstractFunction提供了一些抽象方法
execute() //主要业务逻辑。入参:Jmeter上次运行的SampleResult和当前运行Sampler;出参:String类型的运行结果。注意,如果该方法操作的对象是文件,需要将对该方法进行线程同步保护。
setParameters() //接收用户传递的参数。
getReferenceKey() //获取函数的名称。JMeter的命名规则为"__Xxx"(双下划线),例如:__CSVReadX。
getArgumentDesc() //参数说明。Jmeter函数助手界面显示参数说明。
checkParameterCount() //校验实际接收的参数个数是否符合要求
函数开发时,需要实现上述方法。
具体实现
函数名称
定义:
private static final String KEY = "__CSVReadX";
获取函数名称:
public String getReferenceKey() {
return KEY;
}
参数说明
定义:
private static final List desc = new LinkedList();
static {
desc.add(JMeterUtils.getResString("csvread_file_file_name"));//从Jmeter源码中的message.properties文件中取参数说明
desc.add(JMeterUtils.getResString("column_number"));
desc.add("delimiter");//直接取delimiter作为说明
}
获取参数说明:
public List<String> getArgumentDesc() {
return desc;
}
获取参数值
private Object[] values;//存放参数值
public void setParameters(Collection parameters) throws InvalidVariableException {
log.debug("setParameter - Collection.size=" + parameters.size());
this.values = parameters.toArray();
if (log.isDebugEnabled()) {
for(int i = 0; i < parameters.size(); ++i) {
log.debug("i:" + ((CompoundVariable)this.values[i]).execute());
}
}
if (this.values.length < 2) {
throw new InvalidVariableException("Wrong number of parameters; 2 > " + this.values.length);
} else {
FileWrapperX.clearAll();
}
}
函数实现功能
public synchronized String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {
String myValue = "";
String fileName = ((CompoundVariable)this.values[0]).execute();
String columnOrNext = ((CompoundVariable)this.values[1]).execute();
String delimiter = ",";
if (this.values.length > 2) {
delimiter = ((CompoundVariable)this.values[2]).execute();
}
log.debug("execute (" + fileName + " , " + columnOrNext + ", delimiter is " + delimiter + ") ");
if (columnOrNext.startsWith("*")) {
FileWrapperX.open(fileName, columnOrNext, delimiter);
return "";
} else if (!columnOrNext.equals("next()") && !columnOrNext.equals("next")) {
try {
int columnIndex = Integer.parseInt(columnOrNext);
myValue = FileWrapperX.getColumn(fileName, columnIndex, delimiter);
} catch (NumberFormatException var8) {
log.warn(Thread.currentThread().getName() + " - can't parse column number: " + columnOrNext + " " + var8.toString());
} catch (IndexOutOfBoundsException var9) {
log.warn(Thread.currentThread().getName() + " - invalid column number: " + columnOrNext + " at row " + FileWrapperX.getCurrentRow(fileName) + " " + var9.toString());
}
log.debug("execute value: " + myValue);
return myValue;
} else {
FileWrapperX.endRow(fileName);
return "";
}
}
代码调试
运用测试类进行代码调试
public class CSVReadTest {
private static final transient Logger log = LoggingManager.getLoggerForClass();
public CSVReadTest() {
}
@Test
public void CSVReadTest() throws Exception {
CSVRead csvRead = new CSVRead();
String path = "/Users/xxx/MySQL.csv";
//参数组装
Collection<CompoundVariable> params1 = FunctionTestHelper.makeParams(new Object[]{path, 0});
csvRead.setParameters(params1);
//执行
String result = csvRead.execute();
System.out.println("result:" + result);
}
}
最后打成Jar包,导入Jmeter的lib/ext目录下,重启Jmeter即可