用Jmeter編寫一個較複雜的測試指令碼

weixin_34148456發表於2018-05-09

測試工具

JMeter 4.0

場景描述

  1. 公司是某電商網站,測試Search框在使用者可以輸入關鍵字後,返回一些相應的關鍵字或者商品資訊等。
  2. 使用者在輸入字元時,每隔0.5秒停頓一次,直到字元輸入完畢;
  3. 使用者輸入的每一個字元都會觸發JS請求Service進行處理,並返回結果;
  4. 長短皆有,有空格和特殊符號;

測試場景

由提供一些關鍵字作為測試資料;

Web Server & Service端

常規場景

  1. 輸入這些關鍵字,檢視其返回的結果;使用使用者最終輸入的完整關鍵字,獲取效能指標;(其作用是模擬使用者使用貼上複製的方式,查詢的使用者行為)
  2. 精確模擬使用者行為,當使用者每次輸入關鍵字的字元時,傳送請求產生大壓力下的情況。並且在每次輸入字元後,使用高斯分佈計時器,延遲0.5秒,偏差值為0.1秒的方式來模擬。指令碼編寫時,外層使用Transaction controller,內層使用Foreach controller的組合來模擬這一行為方式;
  3. 採用20,100 User不同負載下持續10 min的測試方法

異常場景

  1. 增壓測試;(不斷增加壓力,直至達到效能極限)
  2. 定時器定點傳送請求;(不斷加壓,使用類似於秒殺活動場景來檢測伺服器)

測試目的

  1. 通過效能測試建立效能基線;
  2. 監控伺服器在較大壓力下的工作情況,查詢是否有隱藏的弱點;
  3. 分析測試結果資料,確保伺服器叢集的工作負荷預期需求;
  4. 為線上服務維護或異常處理時的策略提供依據;

指令碼編寫

為了模擬使用者行為所編寫的指令碼較為複雜,裡面涉及:

  • BeanShell的指令碼編寫,由於還是有java基礎,所以編寫本身並不難;
  • 計時器的應用,使用高斯計時器(正態分佈計時器)
  • 使用Transaction Controller和ForEach Controller進行測試;

這裡面有幾個小坑:

  1. 指令碼編寫思路是將keyword得到之後,將其按照長度分割成若干子串:

以keyword+key為例:
其分解成:
k
ke
key
keyw
keywo
keywor
keyword
keyword+
keyword+k
keyword+ke
keyword+key

因此需要使用foreach controller來包含HTTP Request Sampler。

  • 注意,但外層的BeanShell指令碼編寫不能使用BeanShell PreProcesser來編寫,因為這樣它就不會使內層的HTTP Request工作,原因不明等以後除錯原始碼才清楚,所以請使用BeanSampler來做這個事情。

  • 在程式碼中如果使用字串賦值,涉及到它本身的變數使用的,需要在變數上加雙引號。
    如圖:


    6725433-744b2d16083ed75a.png
    JmeterScript_UserBehavior_Overview.png
  • 如上圖中的方法keyWordLength()是個宣告;如果需要呼叫就必須在指令碼的下方書寫keyWordLength();否則指令碼並沒有執行;

  1. 通過閱讀Beanshell Sampler中的程式碼可以知道,我最終需要的變數名為keyWd_{子字串下標},這個在jmeter的控制器中,只能使用ForEach Controller。它有三個變數:
  • Input variable prefix,讓你使用變數名的下標;
  • Start index for loop (exclusive),這個就是你下標開始的位置,但是特別坑的是,這個值是被排除在外的,所以如果是從0開始,我只能寫-1;
  • End index for loop (inclusive),這個就是下標的最後一位,按照指令碼中設定的值,我應該寫${keyWdLength}-1;
  • Add "_" before number? 這個請勾選,在未知長度的迴圈中,這個控制器顯得那麼得雪中送炭;
6725433-e2d82a4d1dca0852.png
JmeterScript_Foreach_Controller.png
  1. 因為Foreach controller中為變數自動加下劃線,就省去了變數拼接的問題。實際上,沒有這個控制元件可能要寫更復雜的指令碼才行。


    6725433-c32b17975f88c39e.png
    JmeterScript_Http_request.png
  1. 由於關鍵字存在空格,因此我一開始將關鍵字中的空格統一轉成了%20。但是在實際請求時:

HttpClient會報錯java.net.URISyntaxException: Malformed escape pair at index XX....;

原因在於URL中的%是特殊符號,我在指令碼中的寫法是將關鍵字逐一拼接,因此會有一個關鍵字剛好是隻帶有%,這是非法的。因此,才會報錯。
解決方法:在上圖中的Parameters頁中可以勾選“Encode?”。

  1. 把圖中的Simple Controller改成Transaction Controller就可以了。在較複雜場景中,報告中生成TPS結果是更有價值的資料。

剩下的指令碼就比較簡單了,我就不再贅述。

相關文章