--- title: JMeter for Performance Testing date: 2020-11-30 11:00:00 categories: - DevOps tag: - JMeter toc: true thumbnail: /images/2020-11-30-jmeter-for-performance-testing-images/jmeter-logo.png author: SamueL --- ###### tags: `DevOps` `JMeter` `tutorials` # JMeter for Performance Testing ![](https://i.imgur.com/YwESbhb.png) # Intro 專案上線前為了確認系統穩定性會進行完整的**效能/壓力測試**,此次專案使用[Apache JMeter™](https://jmeter.apache.org/ )作為壓力測試的工具。 <!--more--> # Install 由於Jmeter 100% 使用Java撰寫, 安裝JRE即可執行, 不過還是建議安裝JDK( 部分功能需要使用JDK中的Keytool ) * [Adopt OpenJDK (使用Java 8以上的版本)](https://adoptopenjdk.net/ "下載Adopt OpenJDK") * [Apache JMeter](https://jmeter.apache.org/download_jmeter.cgi "下載Apache JMeter") # Tutorial 使用JMeter主要分為三個步驟: 1. [Test Plan Building(測試腳本建立)](#Test-Plan-Building) 2. [Test Running(執行測試)](#Test-Running) 3. [Test Analysis(測試結果輸出)](#Test-Analysis) ### Test Plan Building 於官網下載JMeter並解壓縮後進到 <font color=#a52a2a>**bin**</font> 目錄後會看到數個執行檔 ![JMeter執行檔](https://i.imgur.com/ObRS29J.png "JMeter執行檔")</p> 由於目前要撰寫測試腳本,需使用GUI模式,故點選 <font color=#a52a2a>jmeter.bat</font> 或 <font color=#a52a2a>jmeterw.cmd</font> ( 啟動後會關閉Shell Console ) ![JMeter Console](https://i.imgur.com/iJpJLSN.png "JMeter Console")</p> 1. <font color=#2894FF>**Test Plan**</font>右鍵 <font color=#a52a2a>Add → Threads(Users) → Thread Group</font> 新增一個 **Thread Group(執行續群組)**, 並可針對該群組設定參數 ![Thread Group](https://i.imgur.com/Xi43Fce.png "Thread Group") * Action to be taken after a Sampler error:當有執行續收到Error Response( Http Code非200 )時要採取甚麼行動 * Number of Threads (users):執行續數量( 模擬使用者數量 ) * Ramp-up period (seconds):幾秒內達到所設定的執行續數量 * Loop Count:每個執行續要執行幾次( <font color=#FF0000>**-1**</font> 或勾選 <font color=#FF0000>**infinite**</font> 代表次數無限 ) * Same user on each iteration:預設是勾選, 每次使用相同的Session( 建議取消勾選達到較真實的測試場景 ) * Specify Thread lifetime:指定執行續存活時長( 若Loop Count為無限的話建議設定 ) 2. <font color=#2894FF>**Thread Group**</font> 右鍵 <font color=#a52a2a>Add → Logic Controller → Transaction Controller</font> 新增 <font color=#2894FF>**Transaction Controller**</font> ![可以把Transaction Controller想成一個完整流程, 故一個Test Plan可以有多個Transection Controller](https://i.imgur.com/HNojSEa.png "可以把Transaction Controller想成一個完整流程, 故一個Test Plan可以有多個Transection Controller") 3. <font color=#2894FF>**Transaction Controller**</font>右鍵 <font color=#a52a2a>Add → Sampler → HTTP Request</font> 新增 <font color=#2894FF>**HTTP Request**</font> ![一個Http Request相當於新增一個API Request, 故一個Transaction Controller可以有多個Http Request](https://i.imgur.com/yGFdYLD.png "一個Http Request相當於新增一個API Request, 故一個Transaction Controller可以有多個Http Request") ![再來針對各API所需設定參數, ex: Protocol, Server Name, Path, Request method...](https://i.imgur.com/Qu4Iffj.png "再來針對各API所需設定參數, ex: Protocol, Server Name, Path, Request method...") 經過以上設定一個基本的測試腳本就完成了, 可以開始進行測試!! ### Test Running 當撰寫腳本時若要測試腳本正確性可以以GUI模式執行測試(點選綠色三角start鍵), 正式進行測試時請使用Command-line模式</p> ><font color=#FF0000>Don't run load test using GUI mode </font> :no_good: ![CLI Mode 提供多個options](https://i.imgur.com/ciTScH8.png "CLI Mode 提供多個options") ### Test Analysis <font color=#2894FF>**Thread Group**</font> 右鍵 <font color=#a52a2a>Add → Listener </font> 可新增多種圖表 ![Listener提供多個測試結果圖表](https://i.imgur.com/QnmDs0u.png "Listener提供多個測試結果圖表")</p> 可根據需求新增不同圖表, 但其實[JMeter有產出完整測試報告](https://jmeter.apache.org/usermanual/generating-dashboard.html )的功能( <font color=#a52a2a>僅限使用CLI Mode</font> ) 要注意的是, 部分圖表需要進行一些設定才能正常顯示, 設定方式為新增properties於 `/bin/user.properties` 1. Generate report dashboard after load test: 使用cli mode時給 `-e` 參數, 告知JMeter測試完成後產出報表。 2. Filtering Configuration: JMeter Report Generator部分圖表採**白名單**制, 若該Http Request的Name不存在於設定的白名單內, 則該圖表不會收集此Http Request資訊。 ```jmeter.reportgenerator.exporter.html.series_filter=^({http-request-name})(-success|-failure)?$``` 於**user.properties**中加上上列property並替換掉 `{http-request-name}`, 若有多個Name則以 **|** 隔開。 3. Transaction Controller configuration: 確保 Transaction Controller 中的 <font color=#2894FF>**Generate parent sample**</font> 是uncheck的狀態。 ![Generate parent sample](https://i.imgur.com/Pn30T6V.png)</p> 4. Specify report output folder: 使用cli mode時給 `-o` 參數指定報表輸出資料夾(<font color=#a52a2a>注意:每次執行測試時皆須清空此資料夾</font>)。 ex: `jmeter -n -t /xxx/xxx.jmx -e -o /jmeter/report` 以上列指令執行測試結束後JMeter會在 `/jmeter/file/report` 底下產出如下圖的資料目錄, 開啟 <font color=#a52a2a>index.html</font> 即可查看完整報表。 ![Report Dashboard](https://i.imgur.com/ows4ALB.png "Report Dashboard") # Advanced * [HTTP Header manager ( 自定義Header )](#HTTP-Header-manager) * [User Defined Variables ( 自定義變數 )](#User-Defined-Variables) * [CSV Data Set Config ( 讀取csv for 測試案例 )](#CSV-Data-Set-Config) * [Regular Expression Extractor ( 以正規表示法抓出特定變數 )](#Regular-Expression-Extractor) ### HTTP Header manager ><font color=#2894FF>**Test Plan**</font>右鍵 <font color=#a52a2a>Add → Config Element → HTTP Header manager</font> 新增 <font color=#2894FF>**HTTP Header manager**</font> HTTP Header manager 可以讓使用者針對每個Request自訂header資訊, ex: User-Agent, Content-Type, Authorization...等, 且可以在任一層新增此設定(若在Test Plan層新增則表示該測試計畫底下所有Http Request 皆附加此設定) ![HTTP Header manager](https://i.imgur.com/wJu8AYO.png "HTTP Header manager")</p> ### User Defined Variables ><font color=#2894FF>**Test Plan**</font>右鍵 <font color=#a52a2a>Add → Config Element → User Defined Variables</font> 新增 <font color=#2894FF>**User Defined Variables**</font> User Defined Variables 概念類似於定義全域變數, 之後可以用替換字元的方式取得該值, 通常會定義Server Name ( 方便測試不同環境, ex: sit, dev ), 這樣同一個腳本只要更改Server Name的變數值就可以切換測試環境。 ![於User Defined Variables定義變數](https://i.imgur.com/etkBfz9.png "於User Defined Variables定義變數") ![可於任一Http Request以替換字元的方式取得](https://i.imgur.com/EvOuVhr.png "可於任一Http Request以替換字元的方式取得")</p> ### CSV Data Set Config ><font color=#2894FF>**Thread Group**</font>右鍵 <font color=#a52a2a>Add → Config Element → CSV Data Set Config</font> 新增 <font color=#2894FF>**CSV Data Set Config**</font> 若想要模擬較真實的測試場景可以先建立好測試用資料, 並由JMeter帶給每一個執行續使用, 讓每個Request的資料更像是由不同使用者建立的:100:。 以下介紹較常用的參數: * Filename:指定檔案路徑 * File encoding:指定檔案編碼 * Delimiter:指定CSV的分隔符號 * Recycle on EOF:當讀取至表單最末行時是否要再從第一筆開始讀取 * Stop thread on EOF:當讀取至表單最末行時是否要停止後續thread的執行(停止發送新的Request) ![CSV Data Set Config](https://i.imgur.com/gIuCaGG.png "CSV Data Set Config") ![CSV檔案範例](https://i.imgur.com/BVnu7WL.png "CSV檔案範例")</p> 可以看到上圖csv的首行我們定義了各欄位的key值,接下來只要在Http Request使用該key值的替換字元JMeter便會自動將value注入, 且會依序讀取每列資料提供給各個執行續使用。 ![Http Request 使用CSV資料](https://i.imgur.com/k12W1IG.png "Http Request 使用CSV資料")</p> ### Regular Expression Extractor ><font color=#2894FF>**Http Request**</font>右鍵 <font color=#a52a2a>Add → Post Preprocessors → Regular Expression Extractor</font> 新增 <font color=#2894FF>**Regular Expression Extractor**</font> 若API有相依性( API-B需使用API-A回傳的資料 ), 則可於API-A的Response提取所需變數並提供給API-B。 ![從API-A的Response提取資料](https://i.imgur.com/FhmV9uo.png "從API-A的Response提取資料") ![API-B使用設定的key值注入API-A取得的資料](https://i.imgur.com/dh44AcE.png "API-B使用設定的key值注入API-A取得的資料")</p> # Extended Resources * [**BlazeMeter**](https://www.blazemeter.com/ ) 如果系統流程繁瑣, 一筆一筆新增Http Request會花費非常多時間, 此時建議可以使用 BlazeMeter 以螢幕錄製的方式建立測試腳本, 並可匯入JMeter 做後續調整。 # Reference [Apache JMeter™](https://jmeter.apache.org/index.html ) [Day 20 Jmeter 壓力測試工具](https://ithelp.ithome.com.tw/articles/10203900?sc=hot )