在做壓力測試的時候常常會遇見一個場景,想要測試的介面需要登入介面返回的token做引數,或者需要其它介面的認證資訊,通常能想到的就是正規表示式提取器,把需要的引數提取出來,傳遞到另一個HTTP請求中。
如果有多個執行緒組的情況下,需要每個執行緒組中都要有登陸請求,這不符合我們的規範,最理想狀態就是獲取token的介面只請求一次。然後登陸的認證資訊,在JMeter測試指令碼中的所有介面請求中都可以使用。
這樣就實現了跨執行緒組傳遞引數,這使得介面之間的關聯更加靈活。
所以:什麼是跨執行緒組關聯呢?就是在不同執行緒組之間實現引數傳遞。
1、JMeter中實現跨執行緒組關聯說明
(1)JMeter中實現跨執行緒組關聯步驟
- 先進行登陸請求。
- 記錄登陸請求返回的Cookie,或者有關登入狀態的token資訊。
如果是Cookie,就用HTTP Cookie管理器獲取。
如果是token,就用提取器進行提取。 - 然後通過函式助手中的
__setProperty
函式,把Cookie值升級為JMeter的全域性屬性,就可以線上程組和執行緒組之間共享了。 - 然後從另一個執行緒組中通過
__property
函式,獲取全域性資料。 - 然後把獲取的Cookie或token,加入到檢視購物車請求中,保持使用者登陸狀態。
如果是Cookie,就用新增到HTTP資訊頭管理器元件中。
如果是token,就新增到請求的引數中。 - 執行指令碼,檢視執行結果。
(2)測試計劃內包含的元件
新增元件操作步驟:
- 建立測試計劃。
- 建立執行緒組:
選中“測試計劃”右鍵 —> 新增 —> 執行緒(使用者) —> 執行緒組
。 - 線上程組中,新增配置元件
HTTP Cookie管理器
元件:選中“執行緒組”右鍵 —> 新增 —> 配置元件 —> HTTP Cookie管理器
。 - 線上程組中,新增取樣器“HTTP請求”元件:
選中“執行緒組”右鍵 —> 新增 —> 取樣器 —> HTTP請求
。 - 線上程組中,新增取樣器“BeanShell 取樣器”元件:
選中“執行緒組”右鍵 —> 新增 —> 取樣器 —> BeanShell 取樣器BeanShell 取樣器
。 - 線上程組中,新增配置元件“HTTP資訊頭管理器”元件:
選中“執行緒組”右鍵 —> 新增 —> 配置元件 —> HTTP資訊頭管理器
。 - 線上程組中,新增監聽器“察看結果樹”元件:
選中“執行緒組”右鍵 —> 新增 —> 監聽器 —> 察看結果樹
。
提示:需要重複新增的元件這裡不重複描述。
最終測試計劃中的元件如下:
點選執行按鈕,會提示你先儲存該指令碼,指令碼儲存完成後會直接自動執行該指令碼。
2、使用者登陸請求的相關操作
(1)進行登陸操作獲取Cookie資訊
請求登陸操作介面如下:
通過新增HTTP Cookie管理器元件,會把伺服器返回來的Cookie資訊,預設儲存到執行緒變數中。
前提:
jmeter.properties
檔案中,設定CookieManager.save.cookies=true
。
然後我們可以通過Debug Sampler
(除錯取樣器)元件,檢視到執行緒變數中的Cookie資料。
如下圖所示:
說明:保持使用者登陸狀態的Cookie資料為:
COOKIE_ECS_ID=daf59ab57d42c0cee3596feb7ad17ff576403601
這樣我們就找到Cookie的值了。
(2)把Cookie資料提升為JMeter的全域性屬性
我們需要通過__setProperty
函式,把Cookie資料提升為JMeter的全域性屬性。這樣該Cookie就可以在JMeter指令碼中,所有執行緒組裡都可以使用了。(也就是可以線上程組和執行緒組之間通訊)
接下來點選:工具 —> 函式助手對話方塊,開啟函式助手。(之前的版本在選項中)
然後選擇__setProperty
函式。
第一行填寫:填寫升級為全域性屬性後的變數名。(自定義即可)
第二行填寫:定義全域性屬性的值。(我們就把Cookie屬性的值,引用到這裡)
Return Original Value of property (default false)?
:返回屬性的原始值(預設為 false),預設即可。
編寫完成如下圖所示:
這樣我們就把Cookie提升為JMeter的全域性屬性了,變數名叫kuayu_session
。
JMeter的全域性屬性就相當於在“測試計劃”介面中定義的使用者定義的變裡。
(3)編寫BeanShell取樣器元件
上面生成的這個函式比較特殊,他必須放到BeanShell Sampler
元件裡面。當把這個函式放到BeanShell取樣器元件裡面後,就相當於把變數kuayu_session
的值,放到了我們宣告的公共空間裡面。
如下圖所示:
3、檢視使用者購物車請求的相關操作
(1)檢視使用者購物車請求內容
標準的Get請求,填寫請求的基本資訊即可。
如下圖所示:
(2)獲取JMeter全域性屬性
因為我們把使用者登陸執行緒組中的Cookie屬性提升為JMeter全域性屬性了。
需要在檢視購物車執行緒組中把全域性屬性中的Cookie屬性獲取到,使用__Property
函式。
開啟函式助手:工具 —> 函式助手對話方塊。(之前的版本在選項中)
選擇__Property
函式。
第一行:填寫要獲取的JMeter全域性屬性的變數名。(即:kuayu_session
)
第二行:重用函式計算值的引用名。(可選填)
預設值:屬性未定義時的預設值。
編輯完,如下圖所示:
提示:在
The result of the function is
中看到對應的內容,表示函式生成成功。
(3)HTTP資訊頭管理器內容
我們需要把上一步獲取到的Cookie資訊,放入查詢購物車的請求中。
因為是Cookie的相關資料,只能放在請求頭的資訊中。(如果要是token,就放在請求的引數中)
編輯介面如下:
這樣檢視購物車請求,就帶有使用者的登陸狀態了。
(4)設定執行緒組的啟動時間
因為我們需要等待前面的登陸執行緒組執行完成後,在進行檢視購物的請求,否則將獲取不到我們需要的Cookie資訊。
這時候就需要設定執行緒組元件介面中的排程器屬性了。
我們把持續時間和啟動延遲都設定成3,表示JMeter指令碼啟動3秒後,再執行檢視購物執行緒組中的內容,並持續3秒鐘。
如下圖所示:
排程器配置(Scheduler Configuration)說明:
- 持續時間(秒):如果選擇了排程程式核取方塊,控制測試執行的持續時間,以秒為單位。
- 啟動延遲(秒):如果選擇了排程程式核取方塊,控制測試在多久後啟動執行,以秒為單位。
4、執行結果說明
我們先來看一下,沒有進行跨執行緒相關設定請求的結果。
如下圖所示:可以看到購物車中沒有任何的資料。
我們再來看一下,進行跨執行緒設定請求的結果。
如下圖所示:可以看到該使用者購物車中的資訊了。
再來看看檢視購物車請求的內容,可以看到請求帶有Cookie資訊。
如下圖所示:
以上就完成了,在JMeter中實現跨執行緒組關聯操作的演示。
5、擴充說明(也很重點)
如上需求,在進行效能測試的時候,我們要保證登陸請求執行緒組中,所有使用者登陸的Cookie或token都儲存好,才能進入到下一個執行緒組中執行其他的跨域關聯請求。
這樣就會有兩種實現方式:
- 像本篇文章一樣,把需要關聯的資料提升到全域性屬性。
但是這種方式只能適用於單執行緒跨域關聯,如果是很多使用者併發進行跨域關聯,該種方式只是把最後一個登陸請求的Cookie或token進行了提升。所以下一個執行緒組中使用的登陸狀態,都是登陸執行緒組最後一個人的請求狀態。 - 第二種方式,把登陸請求中的Cookie或token資訊,提取出來並儲存到一個檔案中。然後在其他關聯跨域請求中,使用引數化的方式,把使用者登陸的Cookie或token資訊,傳入到所需的請求中,從而實現跨域關聯的操作。(推薦)
第二種方式實現步驟:
- 每一個介面放在一個執行緒組中。
- 把登陸介面的返回Cookie資料,寫入到
.csv
檔案中。 - jmeter寫
.csv
檔案,使用BeanShell。取樣器新增後置處理器BeanShell postprocessor
。 - 在下一個跨域關聯介面使用資料,用引數化的方式匯入
.csv
檔案。
只提供BeanShell中的資料儲存程式碼(簡單示例)
import java.io.FileWriter;
import java.io.BufferedWriter;
FileWriter fstream = new FileWriter("C:\\Users\\L\\Desktop\\JMeterScript\\user_session.csv", true);
BufferedWriter out = new BufferedWriter(fstream);
out.write(vars.get("COOKIE_ECS_ID")+"\n");
out.close();
fstream.close();
關於詳細步驟,這裡就不展開說明了。我們舉一反三,實現這個操作,會很有意思的。