一捌肴、背景
JMeter 自帶很多函數(shù)枪眉,但不是所有的函數(shù)都適合我們使用捺檬,我們?cè)跍y(cè)試業(yè)務(wù)時(shí),有時(shí)候就需要處理特別的數(shù)據(jù)或者處理業(yè)務(wù)邏輯時(shí)贸铜,這時(shí)候使用自定義的函數(shù)堡纬,對(duì)測(cè)試來(lái)說(shuō),起到事半功倍的效果蒿秦。
二烤镐、準(zhǔn)備開(kāi)發(fā)環(huán)境
1. 新建JMeter項(xiàng)目
打開(kāi) IDE(我使用的是 IDEA),新建一個(gè) maven 工程棍鳖。擴(kuò)展函數(shù)的Java類的報(bào)名必須是.functions
炮叶,所以在工程的目錄下新增包名functions
碗旅,如圖所示
2. 配置 pom.xml 文件
在配置文件的dependencies
節(jié)點(diǎn)添加 JMeter 的依賴文件。JMeter 版本需要根據(jù)你使用的版本來(lái)決定镜悉。
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>${jmeter.version}</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>${jmeter.version}</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_functions</artifactId>
<version>${jmeter.version}</version>
</dependency>
三祟辟、函數(shù)實(shí)現(xiàn)
1. 新增你的自定義函數(shù)類
在剛才創(chuàng)建的functions
文件夾下新建你的自定義函數(shù)類并繼承父類AbstractFunction
,比如:com.dc.functions
侣肄,如圖所示
下一步旧困,就是我們往這個(gè)函數(shù)類填充我們需要實(shí)現(xiàn)的業(yè)務(wù)邏輯或者處理數(shù)據(jù)的方法。
2. 實(shí)現(xiàn)函數(shù)邏輯
AbstractFunction
抽象類提供4個(gè)抽獎(jiǎng)方法稼锅,在擴(kuò)展的時(shí)候需要一一進(jìn)行實(shí)現(xiàn)吼具。
2.1 變量部分
log
可選。該部分是運(yùn)行函數(shù)時(shí)矩距,輸出日志到 JMeter 整體日志拗盒。
desc
必填,是函數(shù)的參數(shù)名字剩晴,根據(jù)需求锣咒,填寫多少個(gè)。
KEY
必填赞弥,是顯示的函數(shù)名稱。
values
必填趣兄,聲明绽左,表示輸入的函數(shù)值。
2.2 execute方法
public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException
JMeter 會(huì)將上次運(yùn)行的SampleResult和當(dāng)前的Sampler作為參數(shù)傳入到該方法里艇潭,返回值就是在運(yùn)行該function后得到的值拼窥,以String類型返回。
2.3 setParameters 方法
public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException
這個(gè)方法在用于傳遞用戶在執(zhí)行過(guò)程當(dāng)中傳入的實(shí)際參數(shù)值蹋凝。該方法在function沒(méi)有參數(shù)情況下也會(huì)被調(diào)用鲁纠。一般該方法傳入的參數(shù)會(huì)被保存在類內(nèi)全局變量里,并被后面調(diào)用的execute方法中使用到鳍寂。另外改含,我們也可以增加對(duì)傳入?yún)?shù)的檢查機(jī)制,防止出現(xiàn)錯(cuò)誤迄汛。
checkMinParameterCount
檢查最少需要輸入的參數(shù)數(shù)量捍壤,達(dá)不到就自動(dòng)報(bào)錯(cuò)。
checkParameterCount
檢查輸入的參數(shù)個(gè)數(shù)是否符合給定的數(shù)量或者范圍鞍爱,不符合報(bào)錯(cuò)鹃觉。
this.values = collection.toArray();
將輸入的參數(shù)值傳遞到value
。
2.4 getReferenceKey
public String getReferenceKey()
返回就是函數(shù)的名字睹逃。JMeter的命名規(guī)則是在函數(shù)名前面加入雙下劃線__
盗扇。比如__AddInt
,函數(shù)的名字需要類名應(yīng)該一致,而且該名字應(yīng)該以static final
的方式在實(shí)現(xiàn)類定義好疗隶,防止在運(yùn)行過(guò)程中被修改佑笋。
2.5 getArgumentDesc
public List<String> getArgumentDesc()
告訴 JMeter 關(guān)于你實(shí)現(xiàn)函數(shù)的描述。
2.6 最終源代碼實(shí)現(xiàn)
實(shí)現(xiàn)的源代碼如下所示抽减,重要的代碼已經(jīng)有注釋允青。
package com.dc.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.threads.JMeterVariables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
public class AddInt extends AbstractFunction {
private static final Logger log = LoggerFactory.getLogger(AddInt.class);
//顯示的參數(shù)名字
private static final List<String> desc = new LinkedList<>();
static {
desc.add("First int");
desc.add("Second int");
desc.add("Third int");
desc.add("Result Int");
}
/**
* 顯示的函數(shù)名字
*/
private static final String KEY = "__AddInt";
/**
* 參數(shù)值
*/
private Object[] values;
@Override
public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {
JMeterVariables localJMeterVariables = getVariables();
//第一個(gè)整數(shù)
String firstInt = ((CompoundVariable)this.values[0]).execute();
//第二個(gè)整數(shù)
String secondInt = ((CompoundVariable)this.values[1]).execute();
//第三個(gè)整數(shù)
String thirdInt = ((CompoundVariable)this.values[2]).execute();
String sumString = "";
int a = 0;
int b = 0;
int c = 0;
try {
a = Integer.parseInt(firstInt);
b = Integer.parseInt(secondInt);
c = Integer.parseInt(thirdInt);
sumString = Integer.toString(this.addInt(a, b, c));
} catch (NumberFormatException e) {
log.error(e.toString());
}
if ((localJMeterVariables != null) && (this.values.length > 0)) {
localJMeterVariables.put(((CompoundVariable)this.values[values.length - 1]).execute(), sumString);
}
return sumString;
}
//設(shè)置參數(shù)值
@Override
public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException {
checkMinParameterCount(collection, 3);
checkParameterCount(collection, 3);
this.values = collection.toArray();
}
//返回函數(shù)名字
@Override
public String getReferenceKey() {
return KEY;
}
//返回參數(shù)名字
@Override
public List<String> getArgumentDesc() {
return desc;
}
public int addInt(int a, int b, int c) {
return a + b + c;
}
}
3. 打包和部署
3.1 生成 jar 包
代碼經(jīng)單元測(cè)試沒(méi)問(wèn)題后,執(zhí)行命令生成 jar 包卵沉〉唢保可使用mvn package
等命令。
3.2 將 jar 放入到 JMeter
將生成的 jar 包及其依賴的 jar 包史汗,一并放入到JMETER_HOME/lib/ext/
路徑中琼掠,重啟 JMeter 即可。也可以將生成的-jar-with-dependencies.jar
放入到上述指定的 JMeter 目錄中停撞。
3.3 使用擴(kuò)展的函數(shù)
成功重啟 JMeter 后瓷蛙,在函數(shù)助手即可我們自定義擴(kuò)展的函數(shù)。在對(duì)應(yīng)的參數(shù)名稱右邊輸入需要傳入的參數(shù)值即可戈毒。編寫后艰猬,復(fù)制 Function syntax 輸入框的內(nèi)容即可。
3.4 測(cè)試自定義函數(shù)
最后我們創(chuàng)建一個(gè)測(cè)試埋市,使用Dummy Sampler冠桃,在request使用該函數(shù),并添加查看結(jié)果樹(shù)的監(jiān)聽(tīng)器道宅。運(yùn)行成功后食听,在監(jiān)聽(tīng)器上得到6即可。