JMeter的扩展机制使得编写JMeter扩展非常简单,而且其本身使用Java开发,这样使得但凡能使用Java实现的功能,JMeter都可以实现,从而给与JMeter以无穷的想象空间。在实际工作当中,我们往往会遇到JMeter提供的自带的采样器无法满足实际工作的情况,这个情况下,我们需要对JMeter进行扩展。JMeter默认提供了如下比较通用的方式方便用户快速进行二次开发:
- Beanshell sampler:在这种模式下,可以方便的在Beanshell sampler中编写Java代码进行采样器开发,无须自定义class,一种开发模式就是在IDE中写好代码直接拷过来。不足之处在于易用性不好。类似的,是JSR223 sampler,增加了对groovy、js等语言的支持功能更加强大,性能也要比beanshell sampler好
- Java sampler:这种方式需要自行编写class并安装到jmeter中,功能强大,易用性也还不错。
下面我们主要介绍下Java sampler的编写。
新建工程
在idea中新建一个Maven项目,在pom.xml中加入JMeter的依赖:
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>5.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>4.0</version>
</dependency>
注意里面的version与大家实际运行的jmeter版本对上。
然后新建一个package: plugins.client,并新建一个类DemoJavaSamplerClient,该类集成自AbstractJavaSamplerClient,其有一个必须实现的方法runTest,整个类图如下所示:
可以看到,AbstractJavaSamplerClient实现了JavaSamplerClient接口,并包含setupTest(测试开始之前执行)、tearDownTest(测试完成之后执行)、getDefaultParameters(从界面获取参数)、getNewLogger几个方法。我们在DemoJavaSamplerClient中也重写这几个方法,以查看下具体的应用。
具体实现
简单描述下我们提供的功能:在界面上提供一个入参url,然后我们自己编写一个get请求访问该url。如果返回结果为200,则本次采样成功,并把返回的文本值放入到jmeter的变量content中;否则返回500,采样失败。
实际实现过程中,我们使用Unirest进行实际http请求,所以首先在pom中增加对unirest的依赖:
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>
最终实现的代码如下:
public class DemoJavaSamplerClient extends AbstractJavaSamplerClient {
@Override
public void setupTest(JavaSamplerContext context) {
getNewLogger().info("测试执行之前...");
}
@Override
public void teardownTest(JavaSamplerContext context) {
getNewLogger().info("测试执行之后...");
}
@Override
public Arguments getDefaultParameters() {
Arguments arguments = new Arguments();
arguments.addArgument("url", "http://www.baidu.com");
return arguments;
}
@Override
protected Logger getNewLogger() {
return super.getNewLogger();
}
public SampleResult runTest(JavaSamplerContext context) {
getNewLogger().info("测试进行中...");
String url = context.getParameter("url");
SampleResult sr = new SampleResult();
sr.sampleStart();
try{
String content = Unirest.get(url).asString().getBody();
JMeterContextService.getContext().getVariables().put("content", content);
sr.setSuccessful(true);
sr.setResponseCode("200");
sr.setResponseMessage("success");
}catch(Exception e){
sr.setSuccessful(false);
sr.setResponseCode("500");
sr.setResponseMessage(e.getMessage());
}
sr.sampleEnd();
return sr;
}
}
有几个点需要强调说明:
- 通过对JMeterContext的引用使用,我们可以在jmeter上下文中增加、删除variable以供其他采样器等使用
- 如果我们的采样器需要细化连接时间、响应时间等,可以使用SampleResult的setConnectTime、setIdleTime等,甚至我们可以在代码中使用pause、resume等操作控制整个采样的时间,在实际执行过程中插入其他操作
- setSuccess方法控制了采样结果是否成功
然后我们使用mvn package进行打包,因为unirest所依赖的httpcomponent和json在jmeter中都已存在,所以只需要把unirest-java的包一起放到<jmeter_home>/lib/ext下即可。
验证
新建一个threadgroup,然后新建一个Java Request,从右侧的下拉列表中选择DemoJavaSamplerClient:
然后新建一个beanshell sampler来获取我们添加的jmeter variable:
String content = vars.get("content");
log.info(content);
最后添加一个结果树,运行。
可以看到测试结果、responsecode和responsemessage与我们设定的值一致:
从jmeter的log里面,我们也可以验证setupTest、runTest和teardownTest的执行顺序与我们分析的一致:
同时也能看到beanshell sampler中输出的百度首页内容。
下面我们更改下url地址,输入一个不存在的地址http://www.c.c,再次执行,可以得到结果如下:
同时也能看到beanshell sampler中的结果为null:
总结
Java sampler的使用,使得JMeter的无限扩展成为可能,功能强大、操作简单,建议大家都掌握。
关注:测试领域专家(头条&微信)获取第一时间文章更新。