『動善時』JMeter基礎 — 38、JMeter中實現跨執行緒組關聯
在做壓力測試的時候常常會遇見一個場景,想要測試的介面需要登錄介面返回的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();
關於詳細步驟,這裡就不展開說明了。我們舉一反三,實現這個操作,會很有意思的。