解锁JMeter(二)——JMeter自定义JavaSampler

Git Parameter

阅读本文大约需要10分钟

JMeter提供了多种取样器,包括HTTP请求,Bean Shell Sampler, JDBC Request……可以支持大部分的请求。除此之外,如果公司使用了自定义的接口协议,JMeter依然可以强大地支持。JMeter提供了自定义Java请求,通过选择自定义指定类型的Java类,以及填写指定的入参,便可以调用指定协议的Java请求。

Git Parameter

Git Parameter

下面开始介绍如何编写自定义的Java Sampler类。

新建工程

使用IDEA(或Eclipse)新建一个maven工程, pom.xml文件中引入ApacheJMeter_core和ApacheJMeter_java包,如果自己的接口协议包包含了与ApacheJMeter共用的包,需要将其排除。如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>${jmeter-version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>${jmeter-version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>

代码编写

新建JavaSampler类实现JavaSamplerClient类,并实现未实现的方法。

1.getDefaultParameters

1
2
3
4
5
6
7
//设置默认参数
public Arguments getDefaultParameters() {
Arguments args = new Arguments();
args.addArgument("name", "yoyo.zhang");
args.addArgument("nums", "1,2,3");
return args;
}

此方法设置入参变量名及默认值,设置之后,会自动加载到JMeter GUI的参数列表中。

2.setupTest

1
2
3
4
5
 //初始化运行数据
public void setupTest(JavaSamplerContext javaSamplerContext) {

name = javaSamplerContext.getParameter("name") == null ? "My Dear" : javaSamplerContext.getParameter("name");
}

相当于Junit或TestNg中的@BeforeClass,在执行方法之前,先初始化线程的公用部分,每个线程都只执行一次。

3.runTest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//执行测试主体
public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
SampleResult sampleResult = new SampleResult();
try {
String nums = javaSamplerContext.getParameter("nums");
String[] numArrays = nums.split(",");
Map<String, String> result = new HashedMap();
//设置开始取样
sampleResult.sampleStart();
for (String num : numArrays) {
try {
Long dig = Long.valueOf(num);
Long res = 1L;
for (Long i = 1L; i <= dig; i++) {
res = res * i;
}
result.put(num + "!", res + "");
} catch (Exception e) {
result.put(num, e.getMessage());
}
}
//设置结束取样
sampleResult.sampleEnd();
//设置请求内容
sampleResult.setSamplerData(name + "\n" + nums);
//设置响应数据
sampleResult.setResponseData("Hi," + name + "!\nThe n! result of your input is\n" + result + "", "UTF-8");
//设置结果为成功
sampleResult.setSuccessful(true);
//设置Response code为200
sampleResult.setResponseCodeOK();
} catch (Exception e) {
//设置结果为失败
sampleResult.setSuccessful(false);
//设置取样器结果中的Response code
sampleResult.setResponseCode("999");
//设置取样器结果中的Response message
sampleResult.setResponseMessage(e.getMessage());
e.printStackTrace();
}
return sampleResult;
}

性能测试的线程运行体,测试执行主体,从入参javaSamplerContext中获取参数值,并在
sampleResult.sampleStart();与sampleResult.sampleEnd();
之间编写调用被测方法的代码,完成与服务器的交互。该方法是java Sampler实现的重点,执行次数取决于线程数和循环次数。

4.teardownTest

1
2
3
4
//结束清理
public void teardownTest(JavaSamplerContext javaSamplerContext) {
//do something like @AfterClass
}

相当于Junit或TestNg中的@AfterClass,测试主体执行结束之后,运行该方法,可根据需要编写代码。

5.本地调试的main方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {
JavaSampler javaSampler = new JavaSampler();

Arguments params = new Arguments();
params.addArgument("name", "Yoyo.Zhang");
params.addArgument("nums", "20,2,3,4,5;2");

//或者直接使用默认参数值
// Arguments params = javaSampler.getDefaultParameters();

JavaSamplerContext javaSamplerContext = new JavaSamplerContext(params);
javaSampler.setupTest(javaSamplerContext);
SampleResult sampleResult = javaSampler.runTest(javaSamplerContext);
System.out.println(sampleResult.getResponseDataAsString());
javaSampler.teardownTest(javaSamplerContext);
}

直接在main方法上调用自定义的JavaSampler类,省去打jar包,重启JMeter等时间。

打jar包

1.File>Project Structure>Project Settings>Artifacts> + > Jar >Empty > + Module Output > OK

Git Parameter

2.Build>Build Artifacts…>选择上一步配置的jar名称>Build

Git Parameter

3.打包结束后,在out\artifacts目录下可以找到jar包,
如%PROJECT_PATH%\out\artifacts\jmeter_plugin_jar。

JMeter运行

1.放jar包:将上一步打好的jar包放在%JMETER_HOME%\lib\ext路径下【不能建子目录】,如果依赖的第三方jar包,且%JMETER_HOME%\lib下未找到的,需要将其放在%JMETER_HOME%\lib目录下,若已存在相同的包但版本号不同,保留高版本的jar包,因为优秀的jar包都是向下兼容的。若觉得都统一放在已有的两个文件夹根目录下,有点杂乱,可以参考 JMeter扩展jar包与依赖jar包一文,配置自定义的路径。

2.重启JMeter:切记,新增加或修改jar包,需要重启JMeter才能生效。

3.新建Java请求:参数列表填写参数,点击运行,查看结果

Git Parameter

常见问题解决

1.Java请求中,下拉类名称,找不到新增的JavaSampler

确保main函数能够调试通过,检查jar包地址配置是否正确,是否已经重启JMeter。

2.自定义Java Sampler运行后,请求部分显示”No data to display”

SampleResult需要设置SamplerData信息,代码如“sampleResult.setSamplerData(“请求信息”); ” 。

Git Parameter

注:红框中“取样器结果”,“请求”,“响应数据”三者的内容一般都可以通过SampleResult来设置,可以自行查看都提供了哪些方法。