前言
在之前的博文“JMeter案例優化:測試執行結束后,實現tearDown的幾種方式”中,嘗試了JMeter的循環控制器While Controller,發現還有點小復雜,將學習過程記錄下來,免得遺忘。
注:我使用的是JMeter 5.5
添加While Controller
右擊需要添加While Controller的線程組,選擇Add->Logic Controller->While Controller
添加成功后,界面如下:
最重要的,就是Condition這個文本框了,循環條件。
循環條件
While Controller的循環條件有三種可能值:空,LAST和表達式,下面將一一舉例說明。
1、空:
條件為空時,本循環體中最后一個采樣器執行失敗時退出。
1.1 循環體內最后一個采樣器執行失敗的情形
1.1.1 While Controller中添加兩個Dummy Sampler,分別命名為11和22
1.1.2 改寫22的Response Data,響應中的result字段為1-10的隨機數
{"result": "${__Random(1,10,)}"}
1.1.3 22添加JSON Assertion:result <= 7。則當result>7時,斷言失敗,構造出本采樣器失敗的情形。
^[0-7]?$
?1.1.4 循環提外添加一個Dummy Sampler,當循環結束后,執行本采樣器。
構造完畢,執行一次:
當采樣器22的響應為8時,斷言失敗,循環體內最后一個采樣器的執行結果為fail,滿足循環結束條件,循環結束。
1.2?循環體內非最后一個采樣器執行失敗的情形(第一個采樣器失敗)
?將上例中的11 和 22調換位置,22作為循環體內的第一個采樣器,重新執行
可以看到,雖然22已經斷言失敗了,但是循環繼續。因為循環條件僅判斷循環體內最后一個采樣器的結果。
2、LAST
值為LAST時,有兩個條件
1、循環進入條件:若循環體前面的最后一個采樣器失敗,不進入循環。
2、循環退出條件:當循環體內的最后一個采樣器失敗時退出;
第2條,與表達式為空時一樣。所以我們著重看第一個條件。
2.1 循環體前面的最后一個采樣器成功,進入循環
我們將之前的While Controller復制一份,稍加改造
2.1.1 while Controller表達式改為LAST
2.1.2 循環體內仍然是最后一個采樣器可能出現失敗的情況
2.1.3 循環外的采樣器放到循環體前面去,以便構造循環體前面的最后一個采樣器成功的情形
2.1.4?循環外的采樣器Response Data 修改為
{"result": true}
2.1.5?循環外的采樣器添加JSON Assertion:
這樣,這個采樣器將斷言成功,
執行一下
可見,因循環體前面的最后一個采樣器執行成功,成功進入循環;
并在循環體內的最后一個采樣器執行失敗時,退出循環。
2.2?循環體前面的最后一個采樣器失敗,不進入循環
修改循環外的采樣器的Response Data為:
{"result": false}
這樣斷言將失敗,不會進入循環:
3、循環條件為變量、屬性或函數,將一直循環,直到循環條件變成false
3.1 變量、屬性
?以變量為例,同樣,將前面的While Controller復制一份,稍加改造
3.1.1 11的Response Data 修改為
{"result": false}
?3.1.2 11添加JSON Extractor
?3.1.2 While Controller的Condition修改為${result}
執行結果:
1、進入循環,順序執行11和22采樣器
2、再次判斷:11采樣器的響應result為false,即所獲取的變量${result}為false,滿足循環退出條件,于是循環結束,沒有執行第二輪。
3.2?函數
可以是__jexl3或__groovy函數。當函數的結果為false是,結束循環
比如JMeter案例優化:測試執行結束后,實現tearDown的幾種方式中的例子:
${__jexl3(${__time(,)}-${__P(TESTSTART.MS,)}<=10000)}
當執行時間<=10秒時為true,繼續循環;
當執行時間>10秒時為false,結束循環?。
Tip:循環次數:
JMeter提供了一個變量__jm__<Name of your element>__idx來統計循環次數,比如下圖,循環控制器組件的名稱是While Controller-var,便可以通過${__jm__While Controller-var__idx}來獲取循環次數
從0開始計數:
不過這個變量作用域僅限于循環體內,出了循環體就不能用了。目前還沒想到什么應用場景。
附:__jexl3常用語法總結
${__jexl3(${__Random(0,50,)}==0,)} //數字等于
${__jexl3(${__Random(0,50,)}!=0,)} //數字不等于
${__jexl3("${var}".equals("qwe"),)} //字符串相等
${__jexl3("${var}" eq "qwe",)}
${__jexl3("${var}" == "qwe",)}
${__jexl3(!"${var}".equals("q1we"),)} //字符串不相等
${__jexl3("${var}" ne "qwe1",)}
${__jexl3("${var}" != "qwe",)}
${__jexl3("${var}}".contains("pre"),)} //字符串包含
${__jexl3(!"${var}".contains("pre"),)} //字符串不包含
${__jexl3("${var}".size() < 3,)} //字符串長度,可以用size()或者length(),效果一樣
${__jexl3("${var}".size() > 3,)}
${__jexl3("${var}".size() == 3,)}
${__jexl3("${var}".empty(),re)} //字符串為空
${__jexl3(${__Random(0,50,)}==0 || "${var}".contains("pre"),)} //組合條件zhozho