學了元件作用域,我終於對 JMeter 開竅了

測試老樹發表於2020-11-04

引子

先看一下這個例子,測試計劃“進入考場”下面有一個執行緒組,執行緒組下面有 3 個 HTTP 請求,分別是學生登入、考場 token和進入房間:

它們的處理邏輯是:

  1. 學生登入後,在響應中返回了登入後的 token,使用正規表示式提取器,提取登入 token

  2. 在登入以後,把登入 token 作為 header,去請求“考場token”這個介面,請求後的響應中,返回了考場 token,使用正規表示式提取,下圖是“考場token”請求的 header,使用了 HTTP Header 管理器:

  1. 拿到考場 token 以後,把考場 token 作為 header,去請求“進入房間”介面,下圖是“進入房間”請求的 header,Value定義的是 ${exam_token},就是考場 token,這個 token 是從第 2 個請求“考場token”的響應中,使用正規表示式提取出來的:

回顧一下,首先登陸,登陸後獲取token,然後再獲取考場token,最後進入房間。這個例子的問題就在於,第 2 個請求和第 3 個請求,都設定了 header,這 2 個 HTTP Header Manager 能按我們想的去工作嗎?

執行順序與作用域

執行順序

先了解一下 JMeter 元件的執行順序。JMeter 根據 2 個維度來決定元件的執行順序,第 1 個維度是從上往下,第 2 個維度是元件型別

從上往下,指的是從根節點->父節點->子節點->葉子節點。

元件型別,分為 3 類:

  • 執行緒組、邏輯控制器。
  • 取樣器。
  • 配置元件、前置處理器、定時器、後置處理器、斷言、監聽器。

最後這六個元件型別,都是為取樣器服務的。它們的執行順序如下:

  1. 配置元件(如果存在)

  2. 前置處理器(如果存在)

  3. 定時器(如果存在)

  4. 取樣器(如果存在)

  5. 後置處理器(如果存在且取樣器的結果不為空)

  6. 斷言(如果存在且取樣器的結果不為空)

  7. 監聽器(如果存在且取樣器的結果不為空)

我總結一下加強理解。假設我們新建了 1 個執行緒,想用這個執行緒去發請求。

首先是初始化配置,比如引數化、設定 Header、Cookie 等,配置元件

接著可能需要給執行緒加點引數,比如使用者引數,會用到前置處理器

然後在傳送請求前可能會等待一段時間,新增定時器

準備好以後,就可以傳送請求了,也就是取樣器

如果取樣器什麼資料也沒有返回,那麼就可以直接退出了。

如果返回了資料,使用後置處理器,比如正規表示式提取器,提取想要的資料。

提取之後還有要做驗證,斷言一把。

測試執行的怎麼樣呢,用監聽器看一看。

示例

再結合示例感受一下,請看以下測試計劃,新增了 1 個 執行緒組,包含 3 個 取樣器(HTTP Request 1 2 3):

JMeter 會按以下步驟執行:

  1. 執行緒組(如果有多個執行緒組可以在測試計劃設定是順序執行還是同時執行)
  2. 簡單控制器(父節點)
  3. HTTP Cookie 管理器(配置元件)
  4. 使用者引數(前置處理器)
  5. Synchronizing Timer(定時器)
  6. HTTP 請求 1(取樣器)
  7. 正規表示式提取器(後置處理器)
  8. 響應斷言(斷言)
  9. HTTP Cookie 管理器(配置元件)
  10. 使用者引數(前置處理器)
  11. Synchronizing Timer(定時器)
  12. HTTP 請求 2(取樣器)
  13. 正規表示式提取器(後置處理器)
  14. 響應斷言(斷言)
  15. HTTP 請求 3(取樣器)
  16. 察看結果樹(嚴格來講是與第 6 步並行,也就是取樣器之後)

作用域

第 9 ~ 14 步我用黑色斜體加粗了,因為從圖中的位置來看,“HTTP 請求 2”,前後並沒有元件,但是也被作用上了。

這是因為它們具有相同的作用域,在 JMeter 中,同一層級的元件具有相同的作用域

示例中,新增了一個簡單控制器,然後在下級新增了配置元件、前置處理器、定時器、後置處理器、斷言,和 2 個取樣器(HTTP Request 1 2 )。

簡單控制器是一個執行單元,本身沒有內容,它的作用是把元件進行分組執行:

所以簡單控制器下面的這些同級元件,作用域相同,既會作用於 HTTP Request 1,也會作用於 HTTP Request 2。

配置元件、前置處理器、定時器、後置處理器、斷言、監聽器,這六個元件型別,會作用到範圍內的所有取樣器

層級

在 JMeter 中,上級的作用域包含下級的作用域。

但是下級是不能作用到上級的。

比如示例中的 HTTP Request 3,和簡單控制器是平級,那麼簡單控制器下級的元件,是不會作用到 HTTP Request 3 的。

使用建議

再看看開頭的例子:

有 3 個取樣器,使用者自定義變數和 CSV Data Set Config,都是配置元件,跟取樣器同級,會同時作用到這 3 個取樣器上面。

HTTP Header Manager 也是配置元件,不會作用到學生登入取樣器,因為根據從上往下的維度,它們都位於學生登入取樣器之後。

圖中有 2 個 HTTP Header Manager,你可能會認為它們會分別執行,實際上它們會一起執行!

在同一執行單元中,如果相同型別的元件有多個,會被當做一個一起執行。

我把第 2 個 HTTP Header Manager 稍微改了一下,可以看得很明顯:

考場token的請求,在目錄樹中是第 2 個,但是從結果來看,它的 header,被新增上了我在後面第 3 個請求設定的 header了。

這個結果顯然不是想要的。

所以為了避免混亂,建議在使用 JMeter 新增元件的時候,一是根據先後順序,從上往下合理的放置元件的順序。二是對於配置元件、前置處理器、定時器、後置處理器、斷言這六類元件,因為它們都是為取樣器服務的,如果只想作用於單個取樣器,最好是放在這個取樣器的下級,以避免由於同一作用域相互作用,導致意想不到的結果。

這個例子把 HTTP Header Manager 分別放到各自的取樣器下級,就能按設想執行起來了:

簡要回顧

本文首先引入了我工作中碰到的問題,接著結合示例講解了執行順序、作用域和層級,搞懂了 JMeter 目錄樹是怎麼執行的,最後回到開頭的例子進行了結果分析,給出了在使用時的兩條建議。

如果你覺得這篇文章寫的還不錯的話,關注公眾號“測試老樹”,你的支援就是我寫文章的最大動力。

相關文章