『動善時』JMeter基礎 — 38、JMeter中實現跨線程組關聯

在做壓力測試的時候常常會遇見一個場景,想要測試的接口需要登錄接口返回的token做參數,或者需要其它接口的認證信息,通常能想到的就是正則表達式提取器,把需要的參數提取出來,傳遞到另一個HTTP請求中。

如果有多個線程組的情況下,需要每個線程組中都要有登陸請求,這不符合我們的規範,最理想狀態就是獲取token的接口只請求一次。然後登陸的認證信息,在JMeter測試腳本中的所有接口請求中都可以使用。

這樣就實現了跨線程組傳遞參數,這使得接口之間的關聯更加靈活。

所以:什麼是跨線程組關聯呢?就是在不同線程組之間實現參數傳遞。

1、JMeter中實現跨線程組關聯說明

(1)JMeter中實現跨線程組關聯步驟

  1. 先進行登陸請求。
  2. 記錄登陸請求返回的Cookie,或者有關登錄狀態的token信息。
    如果是Cookie,就用HTTP Cookie管理器獲取。
    如果是token,就用提取器進行提取。
  3. 然後通過函數助手中的__setProperty函數,把Cookie值升級為JMeter的全局屬性,就可以在線程組和線程組之間共享了。
  4. 然後從另一個線程組中通過__property函數,獲取全局數據。
  5. 然後把獲取的Cookie或token,加入到查看購物車請求中,保持用戶登陸狀態。
    如果是Cookie,就用添加到HTTP信息頭管理器組件中。
    如果是token,就添加到請求的參數中。
  6. 執行腳本,查看運行結果。

(2)測試計劃內包含的元件

添加元件操作步驟

  1. 創建測試計劃。
  2. 創建線程組:選中「測試計劃」右鍵 —> 添加 —> 線程(用戶) —> 線程組
  3. 在線程組中,添加配置元件HTTP Cookie管理器組件:選中「線程組」右鍵 —> 添加 —> 配置元件 —> HTTP Cookie管理器
  4. 在線程組中,添加取樣器「HTTP請求」組件:選中「線程組」右鍵 —> 添加 —> 取樣器 —> HTTP請求
  5. 在線程組中,添加取樣器「BeanShell 取樣器」組件:選中「線程組」右鍵 —> 添加 —> 取樣器 —> BeanShell 取樣器BeanShell 取樣器
  6. 在線程組中,添加配置元件「HTTP信息頭管理器」組件:選中「線程組」右鍵 —> 添加 —> 配置元件 —> HTTP信息頭管理器
  7. 在線程組中,添加監聽器「察看結果樹」組件:選中「線程組」右鍵 —> 添加 —> 監聽器 —> 察看結果樹

提示:需要重複添加的組件這裡不重複描述。

最終測試計劃中的元件如下:

image

點擊運行按鈕,會提示你先保存該腳本,腳本保存完成後會直接自動運行該腳本。

2、用戶登陸請求的相關操作

(1)進行登陸操作獲取Cookie信息

請求登陸操作界面如下:

image

通過添加HTTP Cookie管理器組件,會把服務器返回來的Cookie信息,默認存儲到線程變量中。

前提:jmeter.properties文件中,設置CookieManager.save.cookies=true

然後我們可以通過Debug Sampler(調試取樣器)組件,查看到線程變量中的Cookie數據。

如下圖所示:

image

說明:保持用戶登陸狀態的Cookie數據為:COOKIE_ECS_ID=daf59ab57d42c0cee3596feb7ad17ff576403601

這樣我們就找到Cookie的值了。

(2)把Cookie數據提升為JMeter的全局屬性

我們需要通過__setProperty函數,把Cookie數據提升為JMeter的全局屬性。這樣該Cookie就可以在JMeter腳本中,所有線程組裡都可以使用了。(也就是可以在線程組和線程組之間通信)

接下來點擊:工具 —> 函數助手對話框,打開函數助手。(之前的版本在選項中)

然後選擇__setProperty函數。

第一行填寫:填寫升級為全局屬性後的變量名。(自定義即可)

第二行填寫:定義全局屬性的值。(我們就把Cookie屬性的值,引用到這裡)

Return Original Value of property (default false)?:返回屬性的原始值(默認為 false),默認即可。

編寫完成如下圖所示:

image

這樣我們就把Cookie提升為JMeter的全局屬性了,變量名叫kuayu_session

JMeter的全局屬性就相當於在「測試計劃」界面中定義的用戶定義的變里

(3)編寫BeanShell取樣器組件

上面生成的這個函數比較特殊,他必須放到BeanShell Sampler組件裏面。當把這個函數放到BeanShell取樣器組件裏面後,就相當於把變量kuayu_session的值,放到了我們聲明的公共空間裏面。

如下圖所示:

image

3、查看用戶購物車請求的相關操作

(1)查看用戶購物車請求內容

標準的Get請求,填寫請求的基本信息即可。

如下圖所示:

image

(2)獲取JMeter全局屬性

因為我們把用戶登陸線程組中的Cookie屬性提升為JMeter全局屬性了。

需要在查看購物車線程組中把全局屬性中的Cookie屬性獲取到,使用__Property函數。

打開函數助手:工具 —> 函數助手對話框。(之前的版本在選項中)

選擇__Property函數。

第一行:填寫要獲取的JMeter全局屬性的變量名。(即:kuayu_session

第二行:重用函數計算值的引用名。(可選填)

默認值:屬性未定義時的默認值。

編輯完,如下圖所示:

image

提示:在The result of the function is中看到對應的內容,表示函數生成成功。

(3)HTTP信息頭管理器內容

我們需要把上一步獲取到的Cookie信息,放入查詢購物車的請求中。

因為是Cookie的相關數據,只能放在請求頭的信息中。(如果要是token,就放在請求的參數中)

編輯界面如下:

image

這樣查看購物車請求,就帶有用戶的登陸狀態了。

(4)設置線程組的啟動時間

因為我們需要等待前面的登陸線程組執行完成後,在進行查看購物的請求,否則將獲取不到我們需要的Cookie信息。

這時候就需要設置線程組元件界面中的調度器屬性了。

我們把持續時間啟動延遲都設置成3,表示JMeter腳本啟動3秒後,再執行查看購物線程組中的內容,並持續3秒鐘。

如下圖所示:

image

調度器配置(Scheduler Configuration)說明:

  • 持續時間(秒):如果選擇了調度程序複選框,控制測試執行的持續時間,以秒為單位。
  • 啟動延遲(秒):如果選擇了調度程序複選框,控制測試在多久後啟動執行,以秒為單位。

4、運行結果說明

我們先來看一下,沒有進行跨線程相關設置請求的結果。

如下圖所示:可以看到購物車中沒有任何的數據。

image

我們再來看一下,進行跨線程設置請求的結果。

如下圖所示:可以看到該用戶購物車中的信息了。

image

再來看看查看購物車請求的內容,可以看到請求帶有Cookie信息。

如下圖所示:

image

以上就完成了,在JMeter中實現跨線程組關聯操作的演示。

5、拓展說明(也很重點)

如上需求,在進行性能測試的時候,我們要保證登陸請求線程組中,所有用戶登陸的Cookie或token都保存好,才能進入到下一個線程組中執行其他的跨域關聯請求。

這樣就會有兩種實現方式:

  1. 像本篇文章一樣,把需要關聯的數據提升到全局屬性。
    但是這種方式只能適用於單線程跨域關聯,如果是很多用戶並發進行跨域關聯,該種方式只是把最後一個登陸請求的Cookie或token進行了提升。所以下一個線程組中使用的登陸狀態,都是登陸線程組最後一個人的請求狀態。
  2. 第二種方式,把登陸請求中的Cookie或token信息,提取出來並保存到一個文件中。然後在其他關聯跨域請求中,使用參數化的方式,把用戶登陸的Cookie或token信息,傳入到所需的請求中,從而實現跨域關聯的操作。(推薦)

第二種方式實現步驟:

  1. 每一個接口放在一個線程組中。
  2. 把登陸接口的返回Cookie數據,寫入到.csv文件中。
  3. jmeter寫.csv文件,使用BeanShell。取樣器添加後置處理器BeanShell postprocessor
  4. 在下一個跨域關聯接口使用數據,用參數化的方式導入.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();

關於詳細步驟,這裡就不展開說明了。我們舉一反三,實現這個操作,會很有意思的。