1. 程式人生 > >jmeter教程(十二):流程控制終章

jmeter教程(十二):流程控制終章

這篇博文要介紹的邏輯控制器有:Runtime Controller(執行時間控制器)、吞吐量控制器、模組控制器、While Controller(條件迴圈控制器)、ForEach Controller(遍歷控制器)。

Rumtime Controller,就是用來控制指令碼執行多長時間的。

嗯,執行一下,恭喜,你的jmeter卡死了,這個時候,要把控制檯關了,才能關掉jmeter

從本質來說,Runtime Controller,就是一個死迴圈,設定一個時間(Runtime),就是讓這個死迴圈執行多長時間。為了避免jmeter卡死,我們要給java請求加一個定時器

至於定時器,通常用到的就三個:固定定時器、高斯隨機定時器、Synchronizing Timer(同步定時器)。固定定時器,就是每次都等待相同的時間,高斯隨機定時器,可以設定每次等待的時間是隨機的。同步定時器,在效能測試時會用到,這個以後再講。固定定時器和高斯隨機定時器,用於在傳送請求之前,等待一段時間,注意是在傳送請求之前,也就是在java請求上加一個定時器,是先執行定時器,然後執行java請求。

Rumtime Controller執行時間改為3秒

執行,看結果

執行3秒,每個等300毫秒,一共執行10次,結果就是這樣來的

Rumtime Controller執行時間3秒,在Runtime Controller裡面新增7個java請求,每個都是等待1秒,執行之後,結果是什麼呢?

只運行了前面三個請求。

吞吐量控制器,不要想多了,這個和效能測試中的吞吐量,沒有半毛錢關係。吞吐量控制器的作用,通常是在一個迴圈體內,對迴圈次數做一個分配,一些迴圈做這個事務,一些迴圈做另一個事務。

吞吐量,有兩個選項:Total Executions、Percent Executions。前面一個是指定執行次數,後面一個是指定執行的百分比。我們選擇Total Executions,設定吞吐量為5,並新增java請求

執行,結果只執行了一次java請求。執行緒就迴圈一次,吞吐量設為5次,肯定只執行一次了,把執行緒的迴圈次數設為10

儲存,執行,看結果

執行了5次。看下面的指令碼 

執行緒組迴圈10次,兩個迴圈控制器,都是迴圈5次,吞吐量執行次數3次,執行結果會是什麼?學東西,就是要大膽猜想,小心求證。看結果:

只運行了3次,也就是這個Total Executions,是不管作用域的。我們前面講的 僅一次控制器,是與它所在的作用域有關的。然後,吞吐量的另一個選項就是Percent Executions,這個是以百分比的形式來分配迴圈的。

執行緒組迴圈10次,吞吐量控制器為Percent Executions模式,佔比設為30.0%,執行看結果

10的30%,就是3次,這就是結果,把比例設為130%,再次執行

只執行了10次

模組控制器,這個和程式設計中的goto語句非常相似,就是程式執行到某一個步驟,跳轉到另一個地方去執行,執行完了之後,再回來執行這個步驟之後的步驟。這個跳轉,有個限制,也就是隻能跳轉到邏輯控制器上,不能跳到請求上

這裡添加了一個簡單控制器,然後模組控制器,跳轉到這個簡單控制器。那麼執行結果會是什麼呢

分析一下,為什麼結果是這樣的。首先執行java請求1,這個沒有疑問,然後執行模組控制器。跳轉到簡單控制器,執行了java請求3,簡單控制器執行完了,又返回到模組控制器,執行模組控制器後面的步驟,這就是java請求2了。然後再執行簡單控制器,又是java請求3,最後是java請求4。邏輯是不是有點亂亂的。對對對,這種做法是不提倡的,就像程式設計中不提倡用goto語句是一樣的,會使指令碼的邏輯,難於理解。

While Controller,就是在條件成立的情況下,一直迴圈。我們來看一個需求:假如測試一個商城的購物車的功能,我需要不斷地往購物車中新增商品,商品是隨機的,商品的數量也是隨機的。然後,在購物車內商品的總金額達到1000,就下訂單。這個要怎麼實現?這個,用之前學的知道也能實現。

先在測試計劃上新增配置元件——使用者定義的變數,在裡面新增一個變數total,用於儲存購物車上商品的總金額。然後新增一個迴圈控制器,迴圈控制器新增一個java請求來模擬新增商品,在迴圈的後面新增下訂單的請求,實際上還是這個java請求,改下名字而已。看新增商品的請求,引數是一個函式,函式裡又有函式。這兩個函式,都可以在函式助手中找到。外層是intSum函式,用於對int進行求和。前面的引數都是加數,個數不限,最後一個引數是把求和的結果,儲存到一個變數裡面。在這裡,第一個引數是${total},也就是上次購物車中商品的總金額,第二個引數,是一個函式,在20-100之間生成一個隨機數,把這兩個數求和後,儲存到變數total中。現在,主要是的問題是迴圈多少次,total會達到1000?這個是不確定的,我們只能讓迴圈設定成永遠迴圈,然後在迴圈裡面,新增商品的後面新增一個 如果控制器,來判斷total的值。

再接下來的問題,就是如何退出迴圈的問題,在jmeter裡面,沒有black的功能。但是線上程組中有配置,當出現錯誤請求的時候,怎麼處理,我們可以利用這個設定,當total達到1000的時候,執行一個錯誤的請求,從而讓執行緒停止。。。

然後,我們在 如果控制器 裡新增一個,一定會出錯的請求。

但是,這樣,下訂單的請求就永遠執行不到了。所以要把下訂單的請求,新增到http請求的前面,拖上去就可以了。

儲存,執行

是不是很麻煩?那是相當地麻煩。現在改用While Controller來做,把迴圈控制器改為While Controller,條件為${total}<1000,那麼就一直迴圈,新增商品,最後指令碼就是這樣的

注意While Controller的條件,括號裡都說明了,函式或變數,所以不能直接寫${total}<1000,如果寫成這樣,一執行,恭喜你,你的jmeter又卡死了,死迴圈。所以要把判斷表示式,寫到javaScript函式中,這個函式在函式助手中可以找到。然後執行

最後就講講ForEach Controller,這個就是用來遍歷使用者設定的變數的。

看ForEach Controller的設定面板,有五個設定項,分別為:變數字首、迴圈起點、迴圈終點、儲存值的變數、是否加下劃線。這個一般用在遍歷JDBC查詢資料庫查詢出來的結果,在JDBC查詢出來的資料,格式通過是name_1、name_2這樣的,然後就可以遍歷name的值。可以看出這些變數,字首都是name,所以第一行變數字首,就是填這個的。迴圈起點,那就是從第幾個值開始。不填,則預設從第一個變數開始。終點就是迴圈到第幾個變數,就不再迴圈了。比如查詢出來的結果有10個,那麼最後一個就是name_10,但是我迴圈,不想遍歷所有,只想遍歷前五個,那第迴圈終點,就填5。每次迴圈出來的變數,可以儲存在一個變數中,第四行就可以輸入一個變數名,來接收值。如果變數的名稱是name1、name2這樣的,中間沒有加下劃線,那麼最後一個就不要勾選。不過通常不會這樣做,一般都是加下劃線的。關於JDBC的知識,後面會講。我們這裡,現在模擬一下

在ForEach Controller的前面新增一個迴圈控制器,迴圈次數為5,迴圈上新增java請求,引數就是迴圈次數。然後在java請求上新增正則表示式提取器,把迴圈次數提取出來,並賦值給變數

這樣,前面的迴圈就會提取出來5個變數,分別為info_1、info_2...值分別是:第1次請求、第2次請求...那麼在ForEach Controller裡面,就要遍歷這些變數,配置:

然後在ForEach Controller裡面,新增java請求,把value的值,打印出來

儲存,執行,看結果

關於ForEach Controller的迴圈起點,需要注意,我前面說了,不填,則預設是從第1個變數開始迴圈,這是有條件的,也就是變數必須要從_1開始計數,才行,如果不是,則就會出現不是你想要的結果哦

這裡定義了5個變數,但序號是從5開始的。ForEach Controller和以前一樣,儲存執行,結果什麼也沒有執行,把迴圈終點改為9,也一樣,都不執行。改成如下

然後執行,看結果

可以看到,結果只運行了四次,第一個變數,沒有遍歷到。所以就可以得出結果,迴圈的終點,需要比起始變數的序號少1。然後把迴圈的起點改為4,再次執行:

從這裡也可以看到,迴圈起點不填,預設值是0,不是1。

至此,邏輯控制器,就只剩下兩個沒講了,一個是Include Controller,這個就是在一個指令碼中,引入另一個指令碼的,但我測試過,沒用,不知道高版本是怎樣的。還有一個Critical Section Controller,這個是解決執行緒安全問題的,在講JDBC的時候,我會用一個案例來演示這個,並簡單講解一個執行緒安全的問題。