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


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM