JMeter简介
概述
- Apache JMeter 是 Apache 基于 Java 开发的开源压力测试工具
- 最初被设计用于 Web 应用测试,但后来扩展到了其他测试领域,像接口测试
- 但,随着IT行业的快速发展,不同企业或组织需求更加丰富,JMeter默认的功能往往不能满足所有的需求,在一些企业里,会对这款工具进行二次开发
使用前准备
- JDK:Java开发工具包,是所有Java开发或项目运行的基础
- IntelliJ IDEA:一个进行Java项目开发的集成开发环境,也可以使用Eclipse
- JMeter:下载最新版本即可,但插件开发时的依赖版本与使用的JMeter版本保持 一致
函数开发
概述
- JMeter自带函数库中,提供了丰富的函数,并被广泛使用,如__Random、__UUID等
- 可以通过菜单工具->函数助手对话框进行测试,如下图
- 但,不同接口测试、性能测试项目或场景中,有着不同的特性,JMeter自带的函数并不完全满足业务需要
基于JMeter的自定义函数开发,就能满足各类特性业务的需求,在实际的测试中有着非常重要的应用
自定义函数
核心API
- 自定义函数必须继承AbstractFunction类,并重写父类的4个方法
- execute,函数执行逻辑,必需,自定义函数的核心逻辑,并返回经过处理后的内
- getReferenceKey,函数名称,必需,返回一个字符串,表示在JMeter中使用自定义函数的函数名,一般以双下划线开头,如__Operate、__IDNumber
- setParameters,设置函数接收参数值,如果自定义函数有参数,用于接收调用时传递过来的参数,注意使用时,字符串参数不要加双引号
- getArgumentDesc,函数参数描述,如果自定义函数有参数,用于返回函数参数说明
开发步骤
- 创建Maven项目:使用IDEA创建一个Maven项目
- 添加依赖:在项目的pom.xml中依赖ApacheJMeter_java、ApacheJMeter_core,注意与使用的JMeter版本保持一致,依赖见附件
- 自定义函数:
添加自定义函数,继承AbstractFunction类,并覆写其4个方法
execute方法:添加插件逻辑
getReferenceKey方法:返回自定义名称函数,用于在JMeter中调用
setParameters方法:获取传递的参数
getArgumentDesc:返回参数描述
注意,自定义函数必须在*.functions包下 - 打包:使用Maven工具将插件打包成.jar文件,在项目下的target目录中
- 发布:将打包的.jar文件拷贝到JMeter安装目录的lib/ext目录中
- 重启JMeter:重新启动JMeter,此时就可以JMeter中使用.jar包中自定义的函数
示例一:开发一个简单的算术运算函数
- 函数名:__Operate
- 参数:分别为运算符、操作数1、操作数2
- 代码:
package com.lemon.demo.jmeter.functions;
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.util.JMeterUtils;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* @Project: jmeter-functional
* @Site: http://www.lemonban.com
* @Forum: http://testingpai.com
* @Copyright: ©2022 版权所有 湖南省零檬信息技术有限公司
* @Author: sanbao
* @Create: 2022-04-11 17:52
* @Desc: 算术运算函数
**/
public class Operate extends AbstractFunction {
//操作符
private String operate;
//操作数1
private Double first;
//操作数2
private Double second;
/**
* 函数执行逻辑,自定义函数的核心逻辑,并返回经过处理后的内容
* @param previousResult
* @param currentSampler
* @return
* @throws InvalidVariableException
*/
@Override
public String execute(SampleResult previousResult, Sampler currentSampler) {
Double result = 0d;
//算术运算
if ("+".equals(this.operate)) {
result = this.first + this.second;
}else if ("-".equals(this.operate)) {
result = this.first - this.second;
}else if ("*".equals(this.operate)) {
result = this.first * this.second;
}else if ("/".equals(this.operate)) {
result = this.first / this.second;
}
return result.toString();
}
/**
* 设置函数接收参数值,接收JMeter界面用户传递过来的参数
* @param parameters
* @throws InvalidVariableException
*/
@Override
public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
//检查参数个数
checkParameterCount(parameters,3,3);
//获取参数
Object[] params = parameters.toArray();
//获取运算符
CompoundVariable cvOperate = (CompoundVariable) params[0];
this.operate = cvOperate.execute();
//获取操作数1
CompoundVariable cvFirst = (CompoundVariable) params[1];
this.first = Double.parseDouble(cvFirst.execute());
//获取操作数2
CompoundVariable cvSecond = (CompoundVariable) params[2];
this.second = Double.parseDouble(cvSecond.execute());
}
/**
* 函数名称
* @return
*/
@Override
public String getReferenceKey() {
return "__Operate";
}
/**
* 函数参数描述,JMeter界面显示的参数说明
* @return
*/
@Override
public List<String> getArgumentDesc() {
List<String> desc = new LinkedList<String>();
desc.add("运算符");
desc.add("操作数1");
desc.add("操作数2");
return desc;
}
}
示例二:动态生成身份证号码函数
需求:需要一个根据区域动态生成合格的身份证号码的公共函数
函数名:__IDNumber(区域名称),如__IDNumber(长沙市),将返回一个长沙的随机身份证号码
参数:区域
代码:
package com.lemon.demo.jmeter.functions;
import com.lemon.demo.util.IdNumberGenerateUtil;
import lombok.extern.slf4j.Slf4j;
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 java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* @Project: jmeter-plugin
* @Site: http://www.lemonban.com
* @Forum: http://testingpai.com
* @Copyright: ©2022 版权所有 湖南省零檬信息技术有限公司
* @Author: sanbao
* @Create: 2022-04-06 16:35
* @Desc: 身份证号生成函数
**/
@Slf4j
public class IDNumber extends AbstractFunction {
//参数
private String area;
/**
* 函数执行逻辑,自定义函数的核心逻辑,并返回经过处理后的内容
* @param sampleResult
* @param sampler
* @return
* @throws InvalidVariableException
*/
public String execute(SampleResult sampleResult, Sampler sampler) {
//调用身份证生成逻辑
String idNumber = IdNumberGenerateUtil.generate(area);
return idNumber;
}
/**
* 设置函数接收参数值,接收JMeter界面用户传递过来的参数
* @param parameters
* @throws InvalidVariableException
*/
public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
//检查参数个数
checkParameterCount(parameters,0,1);
//获取参数
Object[] params = parameters.toArray();
//获取区域
if(params.length>0) {
CompoundVariable cvArea = (CompoundVariable) params[0];
this.area = cvArea.execute();
}
}
/**
* 函数名称,JMeter界面函数的名称
* @return
*/
public String getReferenceKey() {
return "__IDNumber";
}
/**
* 函数参数描述,JMeter界面显示的参数说明
* @return
*/
public List<String> getArgumentDesc() {
List<String> desc = new ArrayList<String>();
desc.add("Area");
return desc;
}
}
JMeter二次开发方向
- 函数开发,丰富JMeter通用的函数库,加速用例设计中的通用功能开发,如加密/解密、签名生成、随机生成身份证号码等
- 插件开发,丰富JMeter的测试应用场景,有效提升软件产品测试效能,一般主要做取样器开发,如接口自由协议、Java服务请求等
- 基于执行引擎开发,有效解决单独开发的测试平台或工具中,底层执行引擎开发相对复杂、周期长的问题,利用JMeter执行引擎的API进行基础的调用、监听、提取等操作,加速底层执行引擎开发效率;同时,又能弥补JMeter本身做为一个工具的一些缺点,如界面相对复杂、报表少且图形化效果差、不能对测试过程进行审计管理等
- 完全基于JMeter源码开发,JMeter本身产品结构、执行流程相对稳定,并且代码量大,逻辑也相对复杂,直接对源码进行二次开发投入时间长,收益低,一般不这么做;但参考其代码有利于插件开发
上述二次开发内容将是柠檬班《Java高级测试开发》的课程内容
欢迎来到testingpai.com!
注册 关于