通常情況下如果我們希望在每次循環(huán)中都發(fā)出不同的請(qǐng)求,那么可以將可能的請(qǐng)求內(nèi)容放在一個(gè)文件中,并讓CSV Date Config Element從中獲取相應(yīng)的值并交給變量,也可以通過(guò)BeanShell Sampler用腳本來(lái)自己定制變量的值(注意不能使用Pre Processor中的BeanShell PreProcessor來(lái)定制變量,Pre Processor是用來(lái)修改請(qǐng)求中的域的,這個(gè)動(dòng)作發(fā)生在請(qǐng)求被創(chuàng)建以后。也是說(shuō)如果我們?cè)贐eanShell PreProcessor中定義了一個(gè)變量,然后寫(xiě)在請(qǐng)求域中,那么結(jié)果是JMeter先看到了一個(gè)沒(méi)有被賦值的變量,然后把這個(gè)${變量名}式子當(dāng)作字符串處理,然后再執(zhí)行BeanShell PreProcessor。這一點(diǎn)是很多人容易犯錯(cuò)誤的地方),也可以使用Pre Processor直接修改請(qǐng)求中的域,還可以在請(qǐng)求域中寫(xiě)入一個(gè)JMeter函數(shù),直接生成需要的值。
在有些應(yīng)用中,我們希望下一個(gè)請(qǐng)求的內(nèi)容依賴于之前的請(qǐng)求。那么我們可以通過(guò)Post Processor將響應(yīng)中的有用信息抽取出來(lái),然后賦值給一個(gè)變量,以便下次使用。
5. JMeter中的屬性
在JMeter中有Property的概念,他們通常有兩種用處:首先他們代表了JMeter的配置信息(存在JMeter目錄下的bin/jmeter.properties);其次他們可以被用來(lái)作為MemCache使用,以便線程間能夠通信(Properties的get和put方法是線程安全的)。Property的獲取、定義、修改一般是通過(guò)JMeter函數(shù)來(lái)完成的,當(dāng)然也可以通過(guò)強(qiáng)大的BeanShell。
通常當(dāng)我們希望多個(gè)線程之間有某種依賴關(guān)系時(shí)可以使用Property,但是這樣的需求并不多見(jiàn),因?yàn)槲覀兡M的用戶多半都是相互獨(dú)立的,他們并不應(yīng)該知道其他人在干什么。
此外我們還可以將一些常量配置在jmeter.properties文件中,以便在測(cè)試中隨時(shí)使用
6. JMeter中的函數(shù)
有的時(shí)候我們需要執(zhí)行一些簡(jiǎn)單的操作(例如生成一個(gè)隨機(jī)數(shù))而又不希望編寫(xiě)B(tài)eanShell的Code,那么可以考慮使用JMeter中內(nèi)置的一些函數(shù)。這些函數(shù)的格式通常為${__函數(shù)名(參數(shù)1,參數(shù)2...)},他們有兩種方式來(lái)返回自己的執(zhí)行結(jié)果:一種是直接返回,也是說(shuō)JMeter會(huì)在執(zhí)行該函數(shù)后用函數(shù)的返回結(jié)果來(lái)替換原來(lái)調(diào)用函數(shù)的字符串(例如假設(shè)${__method(1,2)}返回world,那么如果我們?cè)谟蛑袑?xiě)hello ${__method(1,2)},則實(shí)際的結(jié)果是hello world)。另一種是通過(guò)參數(shù)(通常是后一個(gè))指定一個(gè)變量后,JMeter會(huì)將執(zhí)行結(jié)果存入該變量。具體使用哪種方式獲得結(jié)果是根據(jù)不同的函數(shù)而定的,JMeter提供了一個(gè)強(qiáng)大的函數(shù)生成器(Options菜單中的Function Helper Dialog選項(xiàng)),其中列出了所有的方法以及可能的函數(shù),并且有方便的幫助文檔,用戶可以通過(guò)該生成器來(lái)生成所需的函數(shù)。
這里有必要再次強(qiáng)調(diào)JMeter讀入一個(gè)域(任何一個(gè)可以填寫(xiě)內(nèi)容的空格)的過(guò)程:當(dāng)JMeter讀入一個(gè)域中的字符串后,會(huì)首先查看其中的是否存在能夠匹配${...}的字符串,如果有則遞歸地解析這個(gè)${...}中的字符串,直到括號(hào)中的字符串不再包含括號(hào)為止。然后再解析這個(gè)${...}是否為一個(gè)函數(shù)或變量,如果是則用其結(jié)果覆蓋原來(lái)的${...}字符串,直至將整個(gè)字符串解析完畢。例如在輸入欄中輸入hello ${__method(${num},2)},而num變量的值為1,則這個(gè)字符串首先被轉(zhuǎn)化為hello ${__method(1,2)},然后由于${__method(1,2)}的值為world,則終這個(gè)域中的內(nèi)容為hello world。
掌握了以上內(nèi)容后基本可以將JMeter中的函數(shù)和變量運(yùn)用自入了,而讀者所需做得事情只是查看手冊(cè)了解那些函數(shù)能夠提供何種功能。(注意有些函數(shù)是不能放入一些特殊的域中的,例如${__threadNum}不能放在Test Plan的變量定義或者User Defined Element中的變量定義域中,具體原因手冊(cè)上講的很明白)
7. JMeter中的BeanShell
在多數(shù)情況下,JMeter提供的功能是不夠我們使用的,我們的測(cè)試用例中可能會(huì)存在一些比較復(fù)雜的邏輯,而這些邏輯又不發(fā)通過(guò)簡(jiǎn)單的函數(shù)來(lái)實(shí)現(xiàn),那么我們必須動(dòng)用強(qiáng)大的BeanShell了(JMeter有一些元素專門(mén)用于在測(cè)試的不同地方加入BeanShell腳本,如BeanShell Sampler)。不幸的是,JMeter的手冊(cè)中并沒(méi)有介紹BeanShell如何使用,而是把責(zé)任全部推給了BeanShell的網(wǎng)站,BeanShell的網(wǎng)站中的確有完整的BeanShell使用手冊(cè),但是我們總不希望為了做測(cè)試又去學(xué)習(xí)一個(gè)腳本語(yǔ)言,因此這里給出了一些BeanShell的簡(jiǎn)單應(yīng)用,如果覺(jué)得不夠的話再去查看更加復(fù)雜的應(yīng)用。
7.1 BeanShell快速上手
BeanShell是面向Java的腳本語(yǔ)言,因此如果你想在完全不會(huì)BeanShell的前提下使用他,那么直接編寫(xiě)Java code可以了。需要注意的是,BeanShell支持若類型的變量,也是不用指定變量類型,只要給他賦值好了,BeanShell知道這個(gè)變量的類型。無(wú)論這個(gè)若類型變量在哪里被使用,其后的代碼都能訪問(wèn)這個(gè)變量,這與強(qiáng)類型俄變量不同。例如:
view plaincopy to clipboardprint?
// Arbitrary code block
{
y = 2; // Untyped variable assigned
int x = 1; // Typed variable assigned
}
print( y ); // 2
print( x ); // Error! x is undefined.
// Arbitrary code block
{
y = 2; // Untyped variable assigned
int x = 1; // Typed variable assigned
}
print( y ); // 2
print( x ); // Error! x is undefined.