『動善時』JMeter基礎 — 39、JMeter中如果(If)控制器詳解

繁華似錦Fighting發表於2021-06-09

1、什麼是邏輯控制器

JMeter官網對邏輯控制器的解釋是:“Logic Controllers determine the order in which Samplers are processed.”

意思是說,邏輯控制器可以控制取樣器(Samplers)的執行順序。

由此可知,控制器需要和取樣器一起使用,否則控制器就沒有什麼意義了。放在控制器下面的所有采樣器,都會當做一個整體,執行時也會一起被執行。

JMeter提供了多種邏輯控制器,它們各個功能都不相同,大概可以分為兩種使用型別:

  • 控制測試計劃執行過程中,節點的邏輯執行順序,如:ForEach Controller(ForEach控制器),Loop Controller(迴圈控制器)、If Controller(如果if控制器)等;
  • 對測試計劃中的指令碼進行分組,方便JMeter統計執行結果,以及進行指令碼的執行時控制等,如:Throughput Controller(吞吐量控制器)、Transaction Controller(事務控制器)等。

2、如果控制器介紹

在實際工作中,當使用JMeter做效能測試指令碼或者介面測試指令碼時,當遇到需要對不同的條件做不同的操作時,我們可以使用JMeter中如果(If)控制器來實現。

新增如果(If)控制器元件操作:選中“執行緒組”右鍵 —> 新增 —> 邏輯控制器 —> 如果(If)控制器

介面如下圖所示:

image

如果(If)控制器元件介面說明:

  • 名稱如果(If)控制器元件的自定義名稱,見名知意最好。
  • 註釋:即新增一些備註資訊,對該如果(If)控制器元件的簡短說明,以便後期回顧時檢視。
  • Expression (must evaluate to true or false):填寫條件表示式,評估結果必須為真或假。
    換句話說,是執行流程驗證的條件,用於決定是否應執行子元件。預設情況下,條件被解釋為truefalseJavaScript程式碼。
  • Interpret Condition as Variable Expression?:將條件解釋為變數表示式?
    意思是說:
    如果不勾選此選項,則輸入的條件表示式,將會使用JavaScript進行解析,得到需要的true/false結果。
    如果勾選此選項:
    1)輸入的條件表示式,不會使用JavaScript進行解析,而是將條件視為JMeter的變數。
    2)如果需要進行條件判斷,則需要使用__jexl3或者__groovy函式,來生成函式表示式。通過函式表示式,得到需要的true/false結果。
  • Evaluate for all children?:條件作用於每個子項進行評估。
    如果勾選該項,則該控制器在每一個子節點執行時前,執行一次。
    預設情況下,該控制器可以對在其下面的所有可執行的元件,進行控制執行,但只在入口執行一次。

說明:

For performance it is advised to check "Interpret Condition as Variable Expression"
and use `__jexl3` or `__groovy` evaluating to true or false or a variable that contains true or false.
${JMeterThread.last_sample_ok} can be used to test if last sampler was successful

意思為:

  • 為了提升效能,建議將“將條件解釋為變數表示式”勾選。
  • 並使用__jexl3或者__groovy函式,來評估表示式條件的真假。
  • 並且${JMeterThread.last_sample_ok}變數,可用於測試最後一個取樣器是否成功。

預設“將條件解釋為變數表示式”是勾選狀態,取消勾選,則上面的提示會變紅。

3、如果控制器的使用

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

新增元件操作步驟

  1. 建立測試計劃。
  2. 建立執行緒組:選中“測試計劃”右鍵 —> 新增 —> 執行緒(使用者) —> 執行緒組
  3. 線上程組中,新增邏輯控制器“如果(If)控制器”元件:選中“執行緒組”右鍵 —> 新增 —> 邏輯控制器 —> 如果(If)控制器
  4. 在邏輯控制器中,新增取樣器“HTTP請求”元件:選中“邏輯控制器”右鍵 —> 新增 —> 取樣器 —> HTTP請求
  5. 線上程組中,新增監聽器“察看結果樹”元件:選中“執行緒組”右鍵 —> 新增 —> 監聽器 —> 察看結果樹

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

image

點選執行按鈕,會提示你先儲存該指令碼,指令碼儲存完成後會直接自動執行該指令碼。

(2)如果控制器介面內容

我們演示使用JavaScript解析表示式的用法,步驟如下:

  1. 取消勾選Interpret Condition as Variable Expression?選項,否則將不能使用JavaScript解析表示式。
  2. 在條件輸入框中,輸入最基本的條件表示式即可。

我編寫了一個恆true的表示式,如下圖所示:

image

(3)HTTP請求介面內容

一個標準的 Get請求,訪問百度首頁,不做過多說明。

如下圖所示:

image

(4)執行結果

因為如果(If)控制器中的表示式為true,所以可以執行它下面的所有取樣器請求。

如下圖所示:

image

如果(If)控制器中的表示式解析結果為false,則該控制器下面的請求則不執行。

4、如果控制器中表示式的寫法

如果(If)控制器中的表示式有兩種方式:

  1. 一種使用JavaScript語言解析條件表示式,表示式為基本的條件表示式寫法。
  2. 另一種是使用__jexl3或者__groovy函式,通過函式表示式,得出我們需要的truefalse結果。

(1)使用JavaScript語言解析表示式

即:取消勾選Interpret Condition as Variable Expression?選項。

最基本的幾種寫法:

  1. 數字判斷表示式:${var}==1
  2. 字串判讀表示式:"${var}"=="字串"
    提示:如果${var}引數化變數取到的值本身就帶雙引號,則前邊不需要加雙引號。
  3. 如果${var}引數化變數的值就是一個布林值,則表示式為:${var}
    但是要注意,布林值變數必須都是小寫的。

說明:${var}表示引數化變數的引用。我們可以引用自定義變數,或者CSV檔案讀取到的資料,在或者是上一個請求中提取來的值。

(2)使用函式來編寫條件表示式

即:勾選Interpret Condition as Variable Expression?選項。

我們需要用到函式助手中的__jexl3或者__groovy函式,直接輸出true/false結果。

下面以__jexl3函式為示例,進行演示。

__jexl3函式介面如下:

image

引數說明:

  • JEXL expression to evaluate:填寫要計算的表示式。
  • Name of variable in which to store the result (optional):給函式結果定義一個可被引用的變數名(可選)。

__jexl3函式條件格式:${__jexl3(條件表示式)}

  • ==是否等於,如${__jexl3(${VAR}==1,)},判斷${VAR}變數是否等於1。
  • !=不等於,如${__jexl3(${VAR}!=1,)},判斷${VAR}變數是否不等於1。
  • !非,如${__jexl3(!(${VAR}!=1),)},對${VAR}!=1的結果取反。
  • &&且和||或,如${__jexl3(${VAR}==1 && "${name}" != "張三",)}
  • >大於或者>=大於等於,如${__jexl3(${count}>=10,)}

編輯好的介面內容如下:

image

提示:

  1. 把生成的__jexl3函式表示式,貼上到如果(If)控制器介面中。
  2. 看到The result of the function is中有值,說明表示式正確,但是上面返回false這個值,不一定正確,還要看指令碼執行中實際的結果。

這樣就完成了使用__jexl3函式編寫表示式的用法。(__groovy函式同理)

說明:

儘可能使用"解釋條件作為變數表示式"選項,然後使用__jexl3或者__groovy函式生成條件表示式。

因為執行模擬大量使用者的效能指令碼時,這樣消耗的資源最小。

WHY?

If Controller使用JavaScript解釋條件,是每個解釋都佔用資源,但本來就是一個測試效能的軟體,不應因解析條件而消耗更多的資源。

即:如果你使用“解釋條件作為變數表示式”,而不是使用Javascript解釋表示式,這樣能節省更多的效能資源。

(3)Evaluate for all children?選項說明

如果你勾選了Interpret Condition as Variable Expression?選項,同時也勾選了Evaluate for all children?選項。

則填寫在如果(If)控制器中的表示式,需要為${JMeterThread.last_sample_ok}

${JMeterThread.last_sample_ok}表示式的意思是:檢查上一個請求是否成功。

而整個控制流程的效果是,控制其下的所有取樣器:

  1. 如果前一個請求為成功,則${JMeterThread.last_sample_ok}為true,否則為false。
  2. 下一個請求拿${JMeterThread.last_sample_ok}的值來判斷是否執行,如果為true,則繼續執行,如果為false則不執行,且後邊的所有請求都不執行。

如下圖所示:

image

5、擴充

有一個小示例:我準備了20多條測試資料,但是我只想執行指定的幾個測試資料。

有什麼解決辦法嗎?

測試資料如下所示:

image

(1)需求:執行指定的用例5

這時我們可以id為作為條件判斷,來執行用例5。

表示式為:${__jexl3(${id} == 5,)}

(2)需求:執行奇偶數用例

  • 執行奇數用例,表示式為:${__jexl3(${id}%2 == 1,)}
  • 執行偶數用例,表示式為:${__jexl3(${id}%2 == 0,)}

(3)執行多條隨機指定用例

  1. 5條以內用||來解決。
  2. 5條以上,使用在構造資料中打標籤的方式來實現。
    image
    run欄位,1表示執行,0表示不執行。
    表示式為:${__jexl3(${run} == 1,)}

(4)提示

以後工作中的控制器千萬不要寫成下面這樣哦!

image

相關文章