從一個問題說起
對于以下測試腳本:

為了能調用進入房間接口,需要從考場接口擷取考場token。為了調用考場接口,需要從登陸接口擷取登陸token。元件說明如下:
- 學生登入,提取登入
傳入下個接口參數。${token}
- 添加HTTP Header Manager:
JMeter元件作用域實踐指南 - 考場token,提取考場
傳入下個接口參數。${exam_token}
- 添加HTTP Header Manager:
JMeter元件作用域實踐指南 - 進入房間
貌似挺合理,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中,同一層級的元件具有相同的作用域!
簡單控制器是一個執行單元,本身沒有内容,它的作用是把元件進行分組:![]()
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元件運作順序,然後參考了實踐指南,發現了同一層級作用域相同這個原理,總結出了使用建議,配置元件、前置處理器、定時器、後置處理器、斷言這六類元件,最好放在取樣器的下級,調整後腳本如期運作。