從一個問題說起
對於以下測試指令碼:
為了能呼叫進入房間介面,需要從考場介面獲取考場token。為了呼叫考場介面,需要從登陸介面獲取登陸token。元件說明如下:
-
學生登入,提取登入
${token}
傳入下個介面引數。 -
新增HTTP Header Manager:
-
考場token,提取考場
${exam_token}
傳入下個介面引數。 -
新增HTTP Header Manager:
-
進入房間
貌似挺合理,HTTP Header Manager會給下方的介面新增請求頭,執行結果真的如我們所料麼?
執行順序
在回答這個問題之前,有必要搞懂JMeter元件的執行順序,它是由2 個維度來決定的:從上往下和元件型別。
從上往下,即目錄樹從上往下。元件型別,分為3類:
- 執行緒組、邏輯控制器。
- 取樣器。
- 配置元件、前置處理器、定時器、後置處理器、斷言、監聽器。
它們的執行順序如下:
-
配置元件(如果存在)
-
前置處理器(如果存在)
-
定時器(如果存在)
-
取樣器(如果存在)
-
後置處理器(如果存在且取樣器的結果不為空)
-
斷言(如果存在且取樣器的結果不為空)
-
監聽器(如果存在且取樣器的結果不為空)
換句話說,假設我們新建了1個執行緒,想用這個執行緒去發請求。
第一步,初始化配置,比如引數化、設定Header、Cookie等,用到配置元件。
第二步,可能需要給執行緒加點引數,比如使用者引數,用到前置處理器。
第三步,在傳送請求前可能會等待一段時間,用到定時器。
第四步,傳送請求,用到取樣器。
第五步,可能需要提取響應資料,比如正規表示式提取器、JMESPath提取器,用到後置處理器。
第六步,驗證結果符合預期,用到斷言。
第七步,檢視請求響應資料和測試結果,用到監聽器。
實踐指南
對於以下所列元件:
JMeter會按以下步驟執行:
- 執行緒組(如果有多個執行緒組可以在測試計劃設定是順序執行還是同時執行)
- 簡單控制器(父節點)
- HTTP Cookie管理器(配置元件)
- 使用者引數(前置處理器)
- Synchronizing Timer(定時器)
- HTTP 請求1(取樣器)
- 正規表示式提取器(後置處理器)
- 響應斷言(斷言)
- HTTP Cookie管理器(配置元件)
- 使用者引數(前置處理器)
- Synchronizing Timer(定時器)
- HTTP 請求2(取樣器)
- 正規表示式提取器(後置處理器)
- 響應斷言(斷言)
- HTTP 請求3(取樣器)
- 察看結果樹(嚴格來講是與第 6 步並行,也就是取樣器之後)
作用域
其中有個觀察作用域實際效果的關鍵元件:HTTP請求2,它的前後並沒有元件,但是也被作用上了。在JMeter中,同一層級的元件具有相同的作用域!
簡單控制器是一個執行單元,本身沒有內容,它的作用是把元件進行分組:
因為簡單控制器通過分組給元件劃分了層級,所以簡單控制器下面的這些同層級元件,作用域相同,既會作用於 HTTP請求1,也會作用於HTTP請求2。注意了!配置元件、前置處理器、定時器、後置處理器、斷言、監聽器,這六個元件,會作用到範圍內的所有取樣器。
除了同級作用域,還有上下級,JMeter的上級作用域包含下級作用域,但是下級是不能作用到上級。比如HTTP請求3,簡單控制器下級的元件,是不會作用到HTTP請求3的。
回答開頭的問題
HTTP Header Manager是配置元件,會作用到範圍內的所有取樣器。這裡有2個HTTP Header Manager,都位於同一層級,它們會一起執行。在JMeter同一執行單元中,如果相同型別的元件有多個,那麼它們會被當做一個一起執行!
測試一下,把最後一個HTTP Header Manager的authorization重新命名為authorization2,檢視考場介面的Headers:
兩個HTTP Header Manager都作用上了。
為了避免混亂,在實際使用時建議:
- 根據先後順序,從上往下合理的放置元件的順序。
- 對於配置元件、前置處理器、定時器、後置處理器、斷言這六類元件,它們都是為取樣器服務的,如果只想作用於單個取樣器,那麼最好放在這個取樣器的下級。
按照建議調整後的測試指令碼如下:
User Defined Variables和CSV Data Set Config,是配置元件,且跟取樣器同級,會同時作用到這 3 個取樣器上面。
小結
本文開頭引入了我在實際工作中碰到的問題,為了解決,先搞懂了JMeter元件執行順序,然後參考了實踐指南,發現了同一層級作用域相同這個原理,總結出了使用建議,配置元件、前置處理器、定時器、後置處理器、斷言這六類元件,最好放在取樣器的下級,調整後指令碼如期執行。