從一個問題說起
對於以下測試腳本:
為了能調用進入房間接口,需要從考場接口獲取考場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元件運行順序,然后參考了實踐指南,發現了同一層級作用域相同這個原理,總結出了使用建議,配置元件、前置處理器、定時器、后置處理器、斷言這六類元件,最好放在取樣器的下級,調整后腳本如期運行。