需求背景:
在进行测试时需要造运单号来测试,但是随机生成的运单号不能通过业务逻辑的校验规则,而使用Beanshell的话每次都需要写较多的脚本而且不能复用,故想自定义一个生成运单号的函数可以直接的进行引用。
需求功能:
支持单号前三位的定制。
由于单号(12位)包括:包、件、笼,而决定一个单号是否是包、件、笼是由运单的前三来决定的,故希望当前三位输入时则按照输入的规则生成12为单号,未输入则按照默认方式直接生成随机的12位运单号
支持对单号在Jmeter上下文进行引用
一个变量有时候不可能只引用一次,故需要定制一个变量能够存储这个变量进行上下文引用
实现方式:
- 下载Jmeter对应版本源码进行二次开发
- 使用JMeter的ApacheJMeter_core和ApacheJMeter_functions库依赖进行二次开发
小编是使用的第二种方式实现的,即引用maven仓库中的Jmeter上述两个jar包即可以进行自定义函数开发了
package名字
JMeter设计让一些核心的类(非UI相关的,比如ApacheJMeter_core等)可以在非UI的方式下运行的时候能被加载进来,这些类会被优先加载。加载这些类的时候是通过命名规则来实现的。所有实现function的类必需包含".functions.",所以我们自定义实现的类里必须包含".functions",比如 "com.xmeter.customized.functions". 当然也可以通过更改jmeter.properties中的配置来实现改变命名规则,如下所示。但是一般来说不推荐更改此项配置。
classfinder.functions.contain=.functions.
步骤:
- 新建Maven工程然后再Maven工程中的pom文件中引用ApacheJMeter_core和ApacheJMeter_functions库,附上pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.jmeter</groupId>
<artifactId>JmeterFunctions</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>JmeterFunctions</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>3.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId> maven-assembly-plugin </artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.xx.util.GenerateSortCode</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2、编写生成运单号的自定义函数
package com.test.jmeter.functions;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
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 org.apache.jmeter.threads.JMeterVariables;
public class WayBillNoGenerator extends AbstractFunction {
private static final List<String> desc = new LinkedList<String>();
// 定义function名称
private static final String KEY = "__WayBillNoGenerator";
private CompoundVariable prefixFormat; //运单前三位前缀
private CompoundVariable varName;//存储变量值的变量名称作为Jmeter上下文引用
// 自定义function的描述
static {
desc.add("运单前三位(可选)");// 设置运单前缀(前3位)
desc.add("存储结果的变量名 (可选)");// 存储运单的变量
}
public WayBillNoGenerator() {
}
// 获取可设置参数
public List<String> getArgumentDesc() {
return desc;
}
@Override
public String execute(SampleResult arg0, Sampler arg1) throws InvalidVariableException {
String wayBillNo = null;
String prefix = prefixFormat.execute().trim();
wayBillNo = WaybillUtil.genWayBillNo(prefix);
if (varName != null) {
JMeterVariables vars = getVariables();
final String varTrim = varName.execute().trim();
if (vars != null && varTrim.length() > 0) {// vars will be null on TestPlan
vars.put(varTrim, wayBillNo);
}
}
return wayBillNo;
}
@Override // 获取函数引用名称
public String getReferenceKey() {
return KEY;
}
@Override
public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
checkParameterCount(parameters, 0, 2);
Object[] values = parameters.toArray();
int count = values.length;
if (count > 0) {
prefixFormat = ((CompoundVariable) values[0]);
}
if (count > 1) {
varName = ((CompoundVariable) values[1]);
}
}
}
由于生成运单号代码涉及某司公司隐私故不放出代码,只放出生成运单号的方法大家参考一下即可,这个方法支持一个参数及运单前缀
public static String genWayBillNo(String prefix ) {
String wayBillNo=null;
long time = System.currentTimeMillis();
String nowTimeStamp = String.valueOf(time / 10000);
Random rand = new Random();
int itime = rand.nextInt(Integer.parseInt(nowTimeStamp));
if(prefix.length()==0) {
prefix =createData(3);
}
wayBillNo = getWaybillNo(suffix, Integer.toString(rand.nextInt(itime)));
System.out.println(wayBillNo);
return wayBillNo;
}
- 打包:
注意:如果打包不涉及到第三方包(Jmeter那2个包除外)引用可以直接进行打包,如果涉及到第三方库的引用需要在pom文件中加上以下部分:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId> maven-assembly-plugin </artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.xx.util.GenerateSortCode</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
- Jmeter引用
打包完成后将jar包放到Jmeter的\lib\ext目录下然后重启Jmeter即可生效,生效后查看Jmeter函数如下图:
- 测试功能是否正常
新建一个sample然后引用自定义函数,查看功能是否正常
我这边加了1个前三位为944的前缀,则生成的单号应该是944开头的单号,然后设置了一个变量,可以在sampler下新增一个debug sampler即可以查看Jmeter的变量设置如下图:
说明自定义函数是OK的
参考:
1、https://www.jianshu.com/p/a88e5cb1d6cb
2、Jmeter time函数、Random函数等