在以前的博文中,Jmeter二次开发——基于Java请求,已介绍了Jmeter二次开发的基础状况,上次分享的是java请求开发,今天来分享下Jmeter中的函数开发。聊到Jmeter的函数,知道Jmeter使用的博友确定很熟悉。Jmeter自带一个函数库,有不少的函数,好比:__P,__Random,函数助手给咱们提供了不少的方便之处。函数助手使用以下所示:
html
但有些时候,自带的函数知足不了真实的测试场景,好比:生成随机手机号。常规作法,应该是设定手机号区号的固定值,再经过__Random函数生成8位随机数,从而拼接成一个手机号,这样的作法的确能够知足,但要想手机号的区段也是随机的呢,是否是就不太好处理了。那就用函数二次开发试试。java
这个是特别须要注意点,以.functions结尾,正常建立包便可。dom
二次开发时,新建的类,须要继承AbstractFunction,这个也是须要注意的。至于为何须要继承AbstractFunction,看源码就能明白,源码以下所示:ide
public abstract class AbstractFunction implements Function { public AbstractFunction() { } public abstract String execute(SampleResult var1, Sampler var2) throws InvalidVariableException; public String execute() throws InvalidVariableException { JMeterContext context = JMeterContextService.getContext(); SampleResult previousResult = context.getPreviousResult(); Sampler currentSampler = context.getCurrentSampler(); return this.execute(previousResult, currentSampler); } public abstract void setParameters(Collection<CompoundVariable> var1) throws InvalidVariableException; public abstract String getReferenceKey(); protected JMeterVariables getVariables() { return JMeterContextService.getContext().getVariables(); } protected void checkParameterCount(Collection<CompoundVariable> parameters, int min, int max) throws InvalidVariableException { int num = parameters.size(); if (num > max || num < min) { throw new InvalidVariableException(this.getReferenceKey() + " called with wrong number of parameters. Actual: " + num + (min == max ? ". Expected: " + min + "." : ". Expected: >= " + min + " and <= " + max)); } } protected void checkParameterCount(Collection<CompoundVariable> parameters, int count) throws InvalidVariableException { int num = parameters.size(); if (num != count) { throw new InvalidVariableException(this.getReferenceKey() + " called with wrong number of parameters. Actual: " + num + ". Expected: " + count + "."); } } protected void checkMinParameterCount(Collection<CompoundVariable> parameters, int minimum) throws InvalidVariableException { int num = parameters.size(); if (num < minimum) { throw new InvalidVariableException(this.getReferenceKey() + " called with wrong number of parameters. Actual: " + num + ". Expected at least: " + minimum + "."); } } protected final void addVariableValue(String value, CompoundVariable[] values, int index) { if (values.length > index) { String variableName = values[index].execute().trim(); if (StringUtils.isNotEmpty(variableName)) { JMeterVariables vars = this.getVariables(); if (vars != null) { vars.put(variableName, value); } } } } }
获取界面所要显示的参数说明函数
函数的主体业务测试
获取函数的名称this
设置参数,接收用户传递的参数线程
检测参数数量是否准确3d
名称自定义,以下所示:调试
private static final String key = "__XXX";
这里须要注意的是:函数开头是以2个下划线开头。
名称定义好了,那如何获取呢?就用咱们刚才说的方法获取便可,以下所示:
@Override public String getReferenceKey() { return key; }
在Jmeter的函数助手中,对应函数都有对应的参数说明,以下所示:
那如何配置能实现呢?代码以下:
private final static List<String> args = new LinkedList<String>(); static{ args.add("界面参数"); }
若是有多个参数怎么办?多个参数,多个args.add便可
获取参数名称,一样用刚才介绍的方法获取便可,以下所示:
@Override public List<String> getArgumentDesc() { return args; }
@Override public void setParameters(Collection<CompoundVariable> args0) throws InvalidVariableException { //检测用户调用函数时,检查参数个数,个数不对则报错 checkParameterCount(args0,3); Object[] params = args0.toArray(); //转换只为string telNum = ((CompoundVariable)params[0]).execute(); start = ((CompoundVariable)params[1]).execute(); end = ((CompoundVariable)params[2]).execute(); }
获取参数值中,能够检测函数的入参个数是否准确,不许确则会报错,报错信息以下所示:
介绍到这,就是函数的核心内容了,该函数要实现什么功能,就是在该方法中处理,示例代码以下所示:
@Override public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException { SampleResult sampleResult1 = new SampleResult(); try { sampleResult1.sampleStart(); int index=getNum(0,telFirst.length-1); String telNum = telFirst[index]; String two = String.valueOf(getNum(1, 888) + 10000).substring(1); String three = String.valueOf(getNum(1, 9100) + 10000).substring(1); tel = telNum + two + three; logger.info("手机号区段:"+ telNum +" 随机生成的手机号是:" + tel); if (varName != null) { JMeterVariables vars = getVariables(); final String varTrim = varName.execute().trim(); if (vars != null && varTrim.length() > 0) { vars.put(varTrim, telNum); } } sampleResult1.setResponseData("手机号区段:"+ telNum +" 随机生成的手机号是:" + tel,"utf-8"); sampleResult1.setSuccessful(true); }catch (Exception e){ sampleResult.setSuccessful(false); e.printStackTrace(); }finally { sampleResult1.sampleEnd(); } return tel; }
写到这里,基本完成了,但仍是得测试下,功能是否正常,若是先打jar包,丢到Jmeter中,发现有bug的话,来来回回处理,就折腾了,因此仍是须要先测试下的。
在test下新建测试类,示例代码以下所示:
import org.junit.Test; public class Function_Test { @Test public void phoneTest() throws Exception { RandomPhoneJmeterFunctions randomPhone= new RandomPhoneJmeterFunctions(); String phoneString = randomPhone.execute(); System.out.println("随机手机号:" + phoneString); } }
测试代码很简单,运行测试类,没有报错并打印出手机号,则说明没有问题。运行后的结果以下所示:
生成jar包就不重复讲了,能够看之前的博文,IDEA的基本操做——导入导出jar包
代码写好后,天然是要在jmeter中验证下功能的,咱们将生成的jar包放到jmeter的\lib\ext文件夹下,若是jmeter已启用,则须要重启哦,否则不会生效。
打开jmeter后,使用函数助手,看新开发的函数是否有展现,以下所示:
生成函数变量,操做以下所示:
新建线程组,并添加http请求,验证码生成的手机号是否是随机的,运行后,查看结果树,以下所示:
也能够经过日志查看,开发的时候,加了响应日志,以下所示:
到此,就说明功能没问题了。函数开发按上述步骤就能够完成,遇到不知足测试场景的时候,就能够本身diy一个了。
最后附上完整代码,以下所示:
private static Logger logger = LogManager.getLogger(RandomPhoneJmeterFunctions.class.getName()); private String tel; //定义函数名称 private static final String KEY = "__RandomPhone"; //定义函数界面显示的参数名称 private static final List<String> desc = new LinkedList<String>(); static{ desc.add("界面参数"); } private static final String[] telFirst = "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153 ".split(","); private CompoundVariable varName; //业务主逻辑 @Override public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException { SampleResult sampleResult1 = new SampleResult(); try { sampleResult1.sampleStart(); int index=getNum(0,telFirst.length-1); String telNum = telFirst[index]; String two = String.valueOf(getNum(1, 888) + 10000).substring(1); String three = String.valueOf(getNum(1, 9100) + 10000).substring(1); tel = telNum + two + three; logger.info("手机号区段:"+ telNum +" 随机生成的手机号是:" + tel); if (varName != null) { JMeterVariables vars = getVariables(); final String varTrim = varName.execute().trim(); if (vars != null && varTrim.length() > 0) { vars.put(varTrim, telNum); } } sampleResult1.setResponseData("手机号区段:"+ telNum +" 随机生成的手机号是:" + tel,"utf-8"); sampleResult1.setSuccessful(true); }catch (Exception e){ sampleResult.setSuccessful(false); e.printStackTrace(); }finally { sampleResult1.sampleEnd(); } return tel; } //获取参数值 @Override public void setParameters(Collection<CompoundVariable> args0) throws InvalidVariableException { //检测用户调用函数时,检测参数个数 checkParameterCount(args0,1); Object[] params = args0.toArray(); if (params.length > 0) { varName = (CompoundVariable) params[0]; } else { varName = null; } } //获取函数的名称 @Override public String getReferenceKey() { return KEY; } //获取界面所要显示的参数说明 @Override public List<String> getArgumentDesc() { return desc; } private static int getNum(int start,int end) { return (int)(Math.random()*(end-1)); }