『動善時』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();

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