在寫JMeter腳本的時(shí)候經(jīng)常需要模擬一些數(shù)據(jù),大部分情況下模擬數(shù)據(jù)一般采用“CSV Data Set Config”從CSV文件中取數(shù)據(jù)。但是使用數(shù)據(jù)文件的問題是不靈活,有多少虛擬用戶可能得準(zhǔn)備多少測(cè)試數(shù)據(jù)。比如,某應(yīng)用的用戶注冊(cè)過程需要提供手機(jī)號(hào)碼,如果采用CSV文件,需要測(cè)試1000虛擬用戶則需要準(zhǔn)備1000個(gè)手機(jī)號(hào)碼,如果測(cè)試過程中要增加虛擬用戶數(shù)目,則需要準(zhǔn)備更多的測(cè)試數(shù)據(jù),這個(gè)過程比較費(fèi)事。對(duì)于某些特殊的有規(guī)律的測(cè)試數(shù)據(jù),我們可以采用動(dòng)態(tài)生成測(cè)試數(shù)據(jù)的方式,比如利用本文介紹的BeanShell。
具體需求
某手機(jī)應(yīng)用的用戶注冊(cè)過程需要提供手機(jī)號(hào)碼,測(cè)試場(chǎng)景中除了用戶注冊(cè)過程中會(huì)被用到之外,不會(huì)對(duì)手機(jī)號(hào)碼產(chǎn)生實(shí)際操作行為(比如發(fā)送短信等),只需要符合在數(shù)據(jù)庫(kù)中表的定義即可(11位char類型)。
實(shí)現(xiàn)
實(shí)現(xiàn)過程需要考慮不同的虛擬用戶在運(yùn)行的時(shí)候不能產(chǎn)生相同的號(hào)碼,另外還需要考慮同一個(gè)虛擬用戶在多次循環(huán)執(zhí)行的情況下也不能產(chǎn)生相同的號(hào)碼。為了實(shí)現(xiàn)上述需求,我們需要有一個(gè)標(biāo)識(shí)虛擬用戶的ID,以及在多次循環(huán)執(zhí)行的情況下標(biāo)識(shí)的當(dāng)前循環(huán)次數(shù)的值。
標(biāo)識(shí)虛擬用戶可以通過JMeter的內(nèi)置function - threadNum來得到,而后者可以通過JMeter提供的計(jì)數(shù)器來實(shí)現(xiàn),先來看一下我們的腳本的結(jié)構(gòu)。“HTTP請(qǐng)求”需要拿到手機(jī)號(hào)碼發(fā)起一個(gè)測(cè)試請(qǐng)求,該手機(jī)號(hào)碼是從一個(gè)名為mobile的JMeter變量里取得的,而該變量是通過“BeanShell PreProcessor”處理之后保存到JMeter的變量里。
BeanShell的實(shí)現(xiàn),具體請(qǐng)看下面的代碼注釋。
import java.text.DecimalFormat;
String strThreadNum = "${__threadNum}"; //取得當(dāng)前的虛擬用戶ID
int thNum = Integer.parseInt(strThreadNum);
String str = "${iterNO}"; //取得該虛擬用戶當(dāng)前的循環(huán)次數(shù)
int i = Integer.parseInt(str);
int mobileNumLastFive = thNum * 10000 + i;
DecimalFormat df = new DecimalFormat( "0000000000" );
String fullNum = 4 + df.format(mobileNumLastFive); //格式化成4開頭的11位手機(jī)號(hào)碼
System.out.println(fullNum);
vars.put("mobile", fullNum); //將手機(jī)號(hào)碼存入名為mobile的變量,該變量可以在“HTTP請(qǐng)求”中用到
計(jì)數(shù)器的定義:如下圖所示,引用名稱是在BeanShell里引用的iterNO變量。
BeanShell實(shí)現(xiàn)的方式的問題在于不是很高效,為了提高效率可以采用JMeter的function來實(shí)現(xiàn),讀者可以參考這篇文章。