JMeter 自定義函數(shù)

一捌肴、背景

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侣肄,如圖所示

函數(shù)類

下一步旧困,就是我們往這個(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)容即可。

函數(shù)助手

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即可。

函數(shù)使用
正確結(jié)果
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末污茵,一起剝皮案震驚了整個(gè)濱河市樱报,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌泞当,老刑警劉巖迹蛤,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異零蓉,居然都是意外死亡笤受,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門敌蜂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)箩兽,“玉大人,你說(shuō)我怎么就攤上這事章喉『蛊叮” “怎么了身坐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)落包。 經(jīng)常有香客問(wèn)我部蛇,道長(zhǎng),這世上最難降的妖魔是什么咐蝇? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任涯鲁,我火速辦了婚禮,結(jié)果婚禮上有序,老公的妹妹穿的比我還像新娘抹腿。我一直安慰自己,他們只是感情好旭寿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布警绩。 她就那樣靜靜地躺著,像睡著了一般盅称。 火紅的嫁衣襯著肌膚如雪肩祥。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天缩膝,我揣著相機(jī)與錄音混狠,去河邊找鬼。 笑死疾层,一個(gè)胖子當(dāng)著我的面吹牛檀蹋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播云芦,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贸桶!你這毒婦竟也來(lái)了舅逸?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤皇筛,失蹤者是張志新(化名)和其女友劉穎琉历,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體水醋,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旗笔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拄踪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝇恶。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惶桐,靈堂內(nèi)的尸體忽然破棺而出撮弧,到底是詐尸還是另有隱情潘懊,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布贿衍,位于F島的核電站授舟,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贸辈。R本人自食惡果不足惜释树,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望擎淤。 院中可真熱鬧奢啥,春花似錦、人聲如沸揉燃。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)炊汤。三九已至正驻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抢腐,已是汗流浹背姑曙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迈倍,地道東北人伤靠。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像啼染,于是被迫代替她去往敵國(guó)和親宴合。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容