周燕 肖玉 王智超
摘? 要: 許多應(yīng)用系統(tǒng)功能日益復(fù)雜,JMeter已有的功能組件時(shí)常無法滿足測(cè)試需求。文章根據(jù)JMeter的開源特性,對(duì)其進(jìn)行二次開發(fā),通過自定義函數(shù)擴(kuò)展其已有功能;詳細(xì)介紹JMeter自定義函數(shù)開發(fā)的原理和流程并給出關(guān)鍵代碼的實(shí)現(xiàn)過程;結(jié)合WebTours系統(tǒng),將完成的自定義函數(shù)應(yīng)用于具體的測(cè)試場(chǎng)景。幫助測(cè)試人員快速掌握自定義函數(shù)的實(shí)現(xiàn)與應(yīng)用,實(shí)現(xiàn)定制化的功能,以滿足個(gè)性化的測(cè)試需求。
關(guān)鍵詞: JMeter; 開源; 自定義函數(shù); 二次開發(fā)
中圖分類號(hào):TP31? ? ? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A? ? ?文章編號(hào):1006-8228(2023)02-135-04
Abstract: Many application systems have increasingly complex functions, and JMeter's existing functional components often fail to meet the test requirements. In this paper, based on the open source characteristics of JMeter, we perform secondary development and extend its existing functions through custom functions. The principle and flow of JMeter custom function development are introduced in detail, and the realization process of key code is given. Combined with the WebTours system, the completed custom functions are applied to specific test scenarios. It helps testers to quickly master the implementation and application of custom functions, realize customized functions, and meet personalized test requirements.
Key words: JMeter; open source; custom functions; secondary development
0 引言
JMeter是Apache基金會(huì)旗下一款優(yōu)秀的性能測(cè)試和接口測(cè)試工具,已經(jīng)被越來越多的公司所采用。與同類的性能測(cè)試工具LoadRunner、接口測(cè)試工Postman相比,其優(yōu)點(diǎn)是100%純Java[1]開發(fā)且開源、有較強(qiáng)的擴(kuò)展性。它擁有豐富的插件、元件和函數(shù)等功能來滿足各種測(cè)試需求。但隨著應(yīng)用系統(tǒng)業(yè)務(wù)邏輯復(fù)雜性的大幅提升,系統(tǒng)的功能也日益?zhèn)€性化,測(cè)試工作的難度陡增。JMeter已有功能更多的是針對(duì)一些通用性的功能而開發(fā),很難滿足這種個(gè)性化的需求。得益于其開源特性,JMeter擁有其他測(cè)試工具所沒有的可靈活擴(kuò)展性,用戶可根據(jù)實(shí)際功能需求和測(cè)試場(chǎng)景,對(duì)JMeter做二次開發(fā)[2],實(shí)現(xiàn)個(gè)性化的測(cè)試需求。JMeter二次開發(fā)一般分為三類情況:自定義組件、自定義請(qǐng)求和自定義函數(shù)。在JMeter中通過函數(shù)可以靈活的獲取動(dòng)態(tài)變化的值,代替錄制腳本時(shí)所設(shè)置的固定值,對(duì)腳本進(jìn)行參數(shù)化,使整個(gè)測(cè)試過程更加貼近實(shí)際的應(yīng)用場(chǎng)景。
1 JMeter函數(shù)介紹
在性能和接口測(cè)試過程中,通常需要將用戶輸入的數(shù)據(jù)提交給服務(wù)器進(jìn)行處理,例如測(cè)試登入功能需要用戶輸入用戶名和密碼。但是每個(gè)用戶登入的用戶名和密碼都不一樣,測(cè)試時(shí)為了模擬真實(shí)的用戶場(chǎng)景,就需要讓用戶輸入的內(nèi)容每次都發(fā)生變化,這個(gè)過程叫做參數(shù)化。
JMeter中的配置元件與前置處理器[3]都可以實(shí)現(xiàn)參數(shù)化,但使用起來較復(fù)雜且不夠靈活,為了能夠更好的幫助用戶進(jìn)行參數(shù)化,JMeter提供了一組庫函數(shù)來幫助用戶生成需要的數(shù)據(jù)。在JMeter菜單選項(xiàng)中的函數(shù)助手對(duì)話框中,可以看到JMeter自帶了許多的庫函數(shù)[4],如常用的RandomString、counter等,如圖1。每個(gè)函數(shù)主要分為上下兩部分,上半部分是函數(shù)參數(shù),所有參數(shù)以表格的形式進(jìn)行展示,左邊為參數(shù)的描述,方便用戶理解參數(shù)的含義,右邊則可由用戶來輸入該參數(shù)相應(yīng)的值;下半部分是函數(shù)的結(jié)果,當(dāng)用戶點(diǎn)擊“生成”按鈕后下方會(huì)展示根據(jù)用戶輸入的參數(shù),該函數(shù)所返回的結(jié)果。同時(shí)JMeter會(huì)根據(jù)函數(shù)名和用戶選擇的參數(shù),自動(dòng)生成函數(shù)的調(diào)用字符串例如:${__RandomString(3,abc123dw,str)},并自動(dòng)做了復(fù)制功能,用戶可以直接拷貝到需要調(diào)用的地方。
不同接口測(cè)試、性能測(cè)試項(xiàng)目或場(chǎng)景中,有不同的特性,已有的這些函數(shù)只能滿足80%的業(yè)務(wù)需要。例如函數(shù)庫中RandomString函數(shù),可以生成指定長(zhǎng)度的隨機(jī)字符串,但在實(shí)際測(cè)試業(yè)務(wù)中,需要的字符串可能還要求有固定的前綴,那么已有庫函數(shù)就無法滿足測(cè)試需求,而自定義函數(shù)剛好可以解決此問題。
2 開發(fā)自定義函數(shù)
JMeter不僅是一個(gè)測(cè)試工具,而且還是一個(gè)優(yōu)秀的框架,其提供了豐富的jar包方便用戶進(jìn)行二次開發(fā),下面將在庫函數(shù)RandomString的基礎(chǔ)上進(jìn)行優(yōu)化擴(kuò)展,開發(fā)一個(gè)自定義函數(shù)PrefixRandomString——帶前綴的隨機(jī)字符串,以此為例介紹自定義函數(shù)開發(fā)的原理和整個(gè)流程。
2.1 選擇開發(fā)工具
JMeter是使用Java開發(fā)的,進(jìn)行二次開發(fā)時(shí)需要使用支持Java的開發(fā)工具,比如Eclipse、IntelliJ IDEA等來編寫自定義函數(shù)。下文中使用開源軟件Eclipse進(jìn)行開發(fā),先在eclipse中選擇菜單File->New->Java Project創(chuàng)建一個(gè)普通的Java項(xiàng)目即可。
2.2 添加依賴的jar包
JMeter安裝目錄lib/ext中的ApacheJMeter_core.jar包,是JMeter中的核心jar包,該jar包中實(shí)現(xiàn)了對(duì)JMeter進(jìn)行二次開發(fā)的一些基本框架和功能。在進(jìn)行開發(fā)時(shí),要依賴該jar包,需要提前導(dǎo)入Java項(xiàng)目的referenced libraries中。
2.3 類的設(shè)計(jì)與實(shí)現(xiàn)
自定義函數(shù)的所有功能都封裝在Java類中,其代碼需要符合JMeter的編碼規(guī)范——擴(kuò)展函數(shù)的Java類,其包名必須是.function,JMeter通過類的命名規(guī)則確保當(dāng)其以非GUI模式運(yùn)行時(shí)一些核心的類也能夠被正常加載。自定義函數(shù)類所在的包名可以參考JMeter自帶庫函數(shù)類所在包的名稱org.apache.jmeter.functions來進(jìn)行命名;同時(shí)該類還要繼承ApacheJMeter_core.jar包中的AbstractFunction 類,并重寫父類中的四個(gè)方法。
⑴ getReferenceKey方法:該方法返回自定義函數(shù)的名稱。每個(gè)函數(shù)都有一個(gè)獨(dú)一無二的名稱,所以必須重寫這個(gè)方法。函數(shù)的名稱反映了其功能,要做到顧名思義,方便用戶使用。根據(jù)JMeter的規(guī)范,函數(shù)名稱一般以雙下劃線開頭,如__RandomString、__Time等,而且建議與類名同名。參考代碼如下:
@Override
public String getReferenceKey() {
return "__PrefixRandomString";
}
⑵ getArgumentDesc方法:該方法描述了函數(shù)的參數(shù)。如果自定義函數(shù)沒有參數(shù),則可以不用重寫這個(gè)方法;如果有參數(shù),為了便于函數(shù)調(diào)用者輸入?yún)?shù),需要在這里返回函數(shù)參數(shù)說明。函數(shù)的參數(shù)一般情況下固定不變,常將其參數(shù)描述存放在全局靜態(tài)變量list中,而在函數(shù)體中直接將這個(gè)list返回,參考代碼如下:
private static final List
static {
args.add("指定前綴(必填)");
args.add("隨機(jī)字符串的長(zhǎng)度(必填,不包括前綴)");
args.add("組成字符串的字符(可選)");
args.add("存儲(chǔ)結(jié)果的變量名(可選)");
}
@Override
public List
return args;
}
⑶ setParameters方法:該方法傳遞用戶調(diào)用過程中傳入的實(shí)際參數(shù)值。對(duì)于有參數(shù)的函數(shù),可以在該方法中獲取用戶調(diào)用函數(shù)時(shí)傳遞過來的參數(shù),并對(duì)參數(shù)的個(gè)數(shù)、類型等進(jìn)行有效性校驗(yàn),保證函數(shù)的健壯性和正確性。參考代碼如下:
public void setParameters(Collection
arg0) throws InvalidVariableException {
//檢查參數(shù)是否為2到4個(gè)
checkParameterCount(arg0, 2, 4);
Object data[]=arg0.toArray();
//獲取前綴
prefix=((CompoundVariable) data[0]).execute();
//獲取長(zhǎng)度
length=Integer.parseInt(((CompoundVariable) data[1])
.execute());
//如果指定了組成字符串的字符,則獲取使用的字符串
if (data.length>2) {
charsToUse=((CompoundVariable) data[2])
.execute().trim();
}
//如果輸入了存儲(chǔ)結(jié)果的變量名,則獲取變量名
if (data.length>3) {
varName=((CompoundVariable) data[3])
.execute().trim();
}
}
⑷ Execute方法:該方法是自定義函數(shù)中最關(guān)鍵的部分。根據(jù)業(yè)務(wù)規(guī)則,實(shí)現(xiàn)自定義函數(shù)的核心邏輯,將最終生成的結(jié)果返回,參考代碼如下:
@Override
public String execute(SampleResult arg0, Sampler
arg1) throws InvalidVariableException {
//最后的結(jié)果由用戶輸入的前綴+隨機(jī)生成的字符串組成
String myValue=prefix;
if (StringUtils.isEmpty(charsToUse))
myValue+=RandomStringUtils.random(length);
else {
myValue+=RandomStringUtils.random
(length, charsToUse);
}
//如果輸入了存儲(chǔ)結(jié)果的變量名,將結(jié)果保存到變量中
if (varName.length()>0) {
JMeterVariables vars=getVariables();
if (vars!=null) {
vars.put(varName, myValue);
}
}
returnmyValue;
}
2.4 單元測(cè)試
完成自定義函數(shù)的開發(fā)后,還需要測(cè)試函數(shù)功能是否正常。一般使用了java語言自帶的單元測(cè)試框架Junit[6]進(jìn)行測(cè)試,開發(fā)工具Eclipse中已經(jīng)集成了JUnit作為單元測(cè)試的工具。
2.5 使用自定義函數(shù)
代碼調(diào)試無誤后,在開發(fā)工具Eclipse中右鍵單擊項(xiàng)目名稱,選擇菜單Export->JAR file將整個(gè)項(xiàng)目打包導(dǎo)出為jar包,拷貝至jmeter安裝目錄lib/ext的文件夾下。JMeter啟動(dòng)時(shí)會(huì)自動(dòng)加載該目錄下符合要求的jar包。
重啟JMeter,打開函數(shù)助手對(duì)話框,在下拉列表中就能看到所開發(fā)的自定義函數(shù),用戶像使用普通的庫函數(shù)一樣使用它即可,如圖2所示。
通過函數(shù)助手界面可以發(fā)現(xiàn),getReferenceKey方法中所返回的函數(shù)名對(duì)應(yīng)著界面下拉列表中的名稱;getArgumentDesc方法中返回的函數(shù)參數(shù)說明對(duì)應(yīng)界面中函數(shù)參數(shù)表格的部分,可以在表格中輸入具體的參數(shù)值;而界面上顯示的結(jié)果則是Execute方法的返回值。下面將在WebTours系統(tǒng)使用該函數(shù)測(cè)試系統(tǒng)的登入功能。
3 WebTours系統(tǒng)案例分析
WebTours系統(tǒng)是LoadRunner自帶的測(cè)試系統(tǒng),可以進(jìn)行簡(jiǎn)單的航班查詢、飛機(jī)訂票、取消航班、登入、退出、注冊(cè)等操作。首先安strawberry-perl-5.10.1.0, 接下來打開WebTours文件夾,雙擊 StartServer.bat,開啟服務(wù)器,然后在瀏覽器中輸入http://127.0.0.1:1080/WebTours/即可訪問系統(tǒng)[5]。在進(jìn)行訂票操作之前,需要先在注冊(cè)頁面,輸入用戶名、密碼以及確認(rèn)密碼完成注冊(cè)。
現(xiàn)使用JMeter對(duì)注冊(cè)功能進(jìn)行并發(fā)測(cè)試,其測(cè)試場(chǎng)景為:批量注冊(cè)100個(gè)用戶,用戶名的命名是以u(píng)ser開頭且長(zhǎng)度為6位的隨機(jī)字符串組成。線程數(shù)為5,循環(huán)20次。具體實(shí)現(xiàn)步驟如下:
⑴ 使用JMeter錄制登入腳本,通過分析post請(qǐng)求cgi-bin/login.pl的參數(shù)可知,username就是注冊(cè)時(shí)用戶輸入的用戶名。
⑵ 測(cè)試要求用戶名以u(píng)ser開頭,使用前面實(shí)現(xiàn)的自定義函數(shù)PrefixRandomString生成帶前綴的隨機(jī)字符串,作為參數(shù)替換錄制時(shí)的用戶名,如圖3所示。
⑶ 修改線程組的場(chǎng)景,設(shè)置線程數(shù)5個(gè),循環(huán)次數(shù)20次,自動(dòng)完成100次注冊(cè)操作。每次進(jìn)行注冊(cè)請(qǐng)求時(shí)JMeter都會(huì)調(diào)用函數(shù)PrefixRandomString生成隨機(jī)的字符串作為用戶名。
⑷ 執(zhí)行JMeter的腳本后,在WebTours安裝目錄WebTours\cgi-bin\users中,可以看到注冊(cè)成功的用戶名,全部以u(píng)ser作為前綴,如圖4所示。
4 結(jié)束語
自定義函數(shù)開發(fā),是軟件測(cè)試人員對(duì)JMeter基礎(chǔ)操作熟悉的前提下所做的高級(jí)操作,也是測(cè)試復(fù)雜系統(tǒng)時(shí)所必備的技能。本文考慮實(shí)際應(yīng)用場(chǎng)景,結(jié)合WebTours系統(tǒng),詳細(xì)介紹了JMeter自定義函數(shù)開發(fā)的整個(gè)流程以及實(shí)際應(yīng)用。有助于軟件測(cè)試人員快速的進(jìn)行自定義函數(shù)的開發(fā),完成個(gè)性化的測(cè)試任務(wù)。JMeter作為一款開源的測(cè)試工具,為用戶提供了更多的靈活性,在實(shí)際應(yīng)用中還可以自定義組件和自定義請(qǐng)求,使JMeter能更好的滿足測(cè)試要求。
參考文獻(xiàn)(References):
[1] 明日科技.Java從入門到精通(第6版)[M].北京:清華大學(xué)出版社,2021
[2] 胡通.大話性能測(cè)試JMeter實(shí)戰(zhàn)[M].北京:人民郵電出版社,2021
[3] 陳志勇,馬利偉,萬龍.全棧性能測(cè)試修煉寶典JMeter實(shí)戰(zhàn)[M].北京:人民郵電出版社,2016
[4] 巴約·艾林勒著,黃鵬譯.JMeter性能測(cè)試實(shí)戰(zhàn)(第2版)[M].北京:人民郵電出版社,2020
[5] 張億軍.JMeter測(cè)試應(yīng)用研究[J].信息技術(shù)與信息化,2021(10):61-64
[6] 賈美麗,康珺.JUnit在單元測(cè)試中的應(yīng)用[J].計(jì)算機(jī)與現(xiàn)代化,2013(8):116-118
作者簡(jiǎn)介:周燕(1985-),女,湖北荊州人,碩士,助教,主要研究方向:軟件開發(fā)、軟件測(cè)試。