壓測工具Jmeter簡單入門教程
-
Jmeter簡介
-
Jmeter的基本概念
百度百科:
Apache JMeter是Apache組織開發的基於Java的壓力測試工具。用於對軟體做壓力測試,它最初被設計用於Web應用測試,但後來擴充套件到其他測試領域。 它可以用於測試靜態和動態資源,例如靜態檔案、Java 小服務程式、CGI 指令碼、Java 物件、資料庫、FTP 伺服器, 等等。JMeter 可以用於對伺服器、網路或物件模擬巨大的負載,來自不同壓力類別下測試它們的強度和分析整體效能。另外,JMeter能夠對應用程式做功能/迴歸測試,通過建立帶有斷言的指令碼來驗證你的程式返回了你期望的結果。為了最大限度的靈活性,JMeter允許使用正則表示式建立斷言
-
我們為什麼使用Jmeter
- 開源免費,基於Java編寫,可整合到其他系統可拓展各個功能外掛
- 支援介面測試,壓力測試等多種功能,支援錄製回放,入門簡單
- 相較於自己編寫框架或其他開源工具,有較為完善的UI介面,便於介面除錯
- 多平臺支援,可在Linux,Windows,Mac上執行
-
Jmeter的基本概念
-
Jmeter安裝配置
-
Windows下Jmeter下載安裝
- 登入 http://jmeter.apache.org/download_jmeter.cgi ,根據自己平臺,下載對應檔案
- 安裝JDK,配置環境變數(具體步驟不做介紹)
-
將下載Jmeter檔案解壓,開啟/bin/jmeter.bat
-
其他平臺安裝Jmeter
- 與Windows平臺一致,除入口檔案不同,例如linux平臺下為/bin/jmeter.sh
-
Jmeter的目錄結構
-
/bin 目錄(常用檔案介紹)
examples:目錄下包含Jmeter使用例項
ApacheJMeter.jar:JMeter原始碼包
jmeter.bat:windows下啟動檔案
jmeter.sh:Linux下啟動檔案
jmeter.log:Jmeter執行日誌檔案
jmeter.properties:Jmeter配置檔案
jmeter-server.bat:windows下啟動負載生成器服務檔案
jmeter-server:Linux下啟動負載生成器檔案
- /docs目錄——Jmeter幫助文件
- /extras目錄——提供了對Ant的支援檔案,可也用於持續整合
- /lib目錄——存放Jmeter依賴的jar包,同時安裝外掛也放於此目錄
- /licenses目錄——軟體許可檔案,不用管
- /printable_docs目錄——Jmeter使用者手冊
-
/bin 目錄(常用檔案介紹)
-
Windows下Jmeter下載安裝
-
Jmeter相關外掛安裝:
-
外掛安裝:
Jmeter的外掛安裝很簡單,只需要下載對應外掛解壓即可。
- 下載地址:http://jmeter-plugins.org/downloads/all/
- 下載後解壓放入:apache-jmeter-2.12\lib\ext\目錄下
-
重啟jmeter
ps:資料庫連結驅動如果需要需要專門下載,例如mysql需要jdbc的jar包,地址:http://dev.mysql.com/downloads/file/?id=462850
使用注意事項:新增第三方外掛並使用後儲存的jmx檔案在未新增該外掛的執行環境下會導致無法開啟該檔案並報錯,請保持環境一致性。
-
用例生成與匯出:
Jmeter的用例格式為jmx檔案,實際為xml格式,感興趣可以學習下自己定製生成想要的jmx檔案。
-
生成原則:
- 每個功能模組為一個獨立的jmx檔案。增加可維護性。(儘量不要將一個jmx檔案放入太多功能,後期維護成本會很高。)
- 模組的私有變數儲存在模組中,多模組共有的(例如伺服器ip埠等)可以考慮存在單獨的檔案中讀取。
- 介面測試不要放太多執行緒,畢竟不是做壓力測試,意義也不大。
-
匯出方法:
- 編寫測試用例
- 檔案——儲存為——確定:
-
生成原則:
-
外掛安裝:
-
Jmeter常用檔案型別
-
Jmx檔案
- 檔案的實際型別:xml
- 檔案樣本:
-
Jmx檔案
<jmeterTestPlan version="1.2" properties="1.8"> <hashTree> <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test" enabled="true"> <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="TestPlan.user_define_classpath"></stringProp> <boolProp name="TestPlan.serialize_threadgroups">false</boolProp> <boolProp name="TestPlan.functional_mode">false</boolProp> <stringProp name="TestPlan.comments">Sample test for demonstrating JMeter Ant build script and Schematic stylesheet</stringProp> </TestPlan> <hashTree> <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true"> <longProp name="ThreadGroup.start_time">1143889321000</longProp> <stringProp name="ThreadGroup.delay"></stringProp> <stringProp name="ThreadGroup.duration"></stringProp> <stringProp name="ThreadGroup.num_threads">3</stringProp> <boolProp name="ThreadGroup.scheduler">false</boolProp> <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true"> <stringProp name="LoopController.loops">5</stringProp> <boolProp name="LoopController.continue_forever">false</boolProp> </elementProp> <longProp name="ThreadGroup.end_time">1143889321000</longProp> <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> <stringProp name="ThreadGroup.ramp_time">1</stringProp> </ThreadGroup> <hashTree> <CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="Counter" enabled="true"> <stringProp name="CounterConfig.start">1</stringProp> <stringProp name="CounterConfig.incr">1000</stringProp> <stringProp name="CounterConfig.name">C</stringProp> <boolProp name="CounterConfig.per_user">false</boolProp> <stringProp name="CounterConfig.end">1000000</stringProp> </CounterConfig> <hashTree/> <JavaSampler guiclass="JavaTestSamplerGui" testclass="JavaSampler" testname="Sample 1" enabled="true"> <elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"> <elementProp name="Sleep_Time" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">100</stringProp> <stringProp name="Argument.name">Sleep_Time</stringProp> </elementProp> <elementProp name="Sleep_Mask" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">0xFF</stringProp> <stringProp name="Argument.name">Sleep_Mask</stringProp> </elementProp> <elementProp name="Label" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value"></stringProp> <stringProp name="Argument.name">Label</stringProp> </elementProp> <elementProp name="ResponseCode" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">200</stringProp> <stringProp name="Argument.name">ResponseCode</stringProp> </elementProp> <elementProp name="ResponseMessage" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">OK</stringProp> <stringProp name="Argument.name">ResponseMessage</stringProp> </elementProp> <elementProp name="Status" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">OK</stringProp> <stringProp name="Argument.name">Status</stringProp> </elementProp> <elementProp name="SamplerData" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">Request</stringProp> <stringProp name="Argument.name">SamplerData</stringProp> </elementProp> <elementProp name="ResultData" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">Response C=${C}</stringProp> <stringProp name="Argument.name">ResultData</stringProp> </elementProp> </collectionProp> </elementProp> <stringProp name="classname">org.apache.jmeter.protocol.java.test.JavaTest</stringProp> </JavaSampler> <hashTree> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="51">3</stringProp> </collectionProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> <intProp name="Assertion.test_type">6</intProp> <stringProp name="Assertion.assume_success">false</stringProp> </ResponseAssertion> <hashTree/> </hashTree> <JavaSampler guiclass="JavaTestSamplerGui" testclass="JavaSampler" testname="Sample 2" enabled="true"> <elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true"> <collectionProp name="Arguments.arguments"> <elementProp name="Sleep_Time" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">100</stringProp> <stringProp name="Argument.name">Sleep_Time</stringProp> </elementProp> <elementProp name="Sleep_Mask" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">0xFF</stringProp> <stringProp name="Argument.name">Sleep_Mask</stringProp> </elementProp> <elementProp name="Label" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value"></stringProp> <stringProp name="Argument.name">Label</stringProp> </elementProp> <elementProp name="ResponseCode" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">200</stringProp> <stringProp name="Argument.name">ResponseCode</stringProp> </elementProp> <elementProp name="ResponseMessage" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">OK</stringProp> <stringProp name="Argument.name">ResponseMessage</stringProp> </elementProp> <elementProp name="Status" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">OK</stringProp> <stringProp name="Argument.name">Status</stringProp> </elementProp> <elementProp name="SamplerData" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">Request</stringProp> <stringProp name="Argument.name">SamplerData</stringProp> </elementProp> <elementProp name="ResultData" elementType="Argument"> <stringProp name="Argument.metadata">=</stringProp> <stringProp name="Argument.value">Response C=${C} Tn=${__threadNum}</stringProp> <stringProp name="Argument.name">ResultData</stringProp> </elementProp> </collectionProp> </elementProp> <stringProp name="classname">org.apache.jmeter.protocol.java.test.JavaTest</stringProp> </JavaSampler> <hashTree/> </hashTree> </hashTree> </hashTree> </jmeterTestPlan> |
-
Jtl檔案
- 檔案的實際型別:自定義
-
定義方法:
修改{jmeterhome}/bin/jmeter.profile,可選擇格式:csv,xml,db
# legitimate values: xml, csv, db. Only xml and csv are currently supported. #jmeter.save.saveservice.output_format=csv |
-
Jmeter執行模式及引數
-
GUI模式
開啟已有的jmx檔案(檔案——開啟)
點選啟動按鈕執行
由於GUI模式本身就是帶介面的,也有中文版,就不在此詳細介紹了。
-
命令列模式
-
依賴:
- 配置jmeter環境變數(windows下為將${jmeterhome}/bin加入Path變數)
- 如果未加入環境變數,在執行的時候可以直接給出全路徑或在${jmeterhome}/bin下執行
-
命令:
jmeter -n -t <testplan filename> -l <listener filename>
-
引數:
- -h 幫助 -> 打印出有用的資訊並退出
- -n 非 GUI 模式 -> 在非 GUI 模式下執行 JMeter
- -t 測試檔案 -> 要執行的 JMeter 測試指令碼檔案
- -l jtl檔案 -> 記錄結果的檔案
- -r 遠端執行 -> 啟動遠端服務
- -H 代理主機 -> 設定 JMeter 使用的代理主機
- -P 代理埠 -> 設定 JMeter 使用的代理主機的埠號
- -j 日誌檔案->設定JMeter日誌檔案的名稱
-
例項:
JMeter -n -t my_test.jmx -l log.jtl -H my.proxy.server -P 8000
-
執行步驟:
JMeter 預設去當前目錄尋找指令碼檔案,並把日誌記錄在當前目錄。比如你在 C:\tools\apache-jmeter-2.11\bin 目錄下執行以上命令,JMeter 會去該目錄下尋找 test.jmx 指令碼並把執行結果放在該目錄。如果你的指令碼在其他目錄,而且想要把執行結果放在另外資料夾,可以使用絕對路徑告訴 JMeter。
- 執行過程檢視:
-
依賴:
-
GUI模式
D:\apache-jmeter-3.0\bin>jmeter -n -t D:\共享\bpintocpin.jmx -l D:\共享\test.jtl Writing log file to: D:\apache-jmeter-3.0\bin\jmeter.log Creating summariser <summary> Created the tree successfully using D:\共享\bpintocpin.jmx Starting the test @ Fri Jun 17 15:12:21 CST 2016 (1466147541295) Waiting for possible Shutdown/StopTestNow/Heapdump message on port 4445 summary = 1 in 00:00:01 = 0.8/s Avg: 1178 Min: 1178 Max: 1178 Err: 0 (0.00%) Tidying up ... @ Fri Jun 17 15:12:22 CST 2016 (1466147542649) ... end of run |
-
執行結果檢視:
-
GUI介面開啟聚合報告
- 在GUI介面建立一個聚合報告
- 聚合報告介面點選瀏覽,選中生成的.jtl檔案,開啟
- 執行過程中檢視
-
GUI介面開啟聚合報告
summary = 1 in 00:00:01 = 0.8/s Avg: 1178 Min: 1178 Max: 1178 Err: 0 (0.00%) |
-
jtl檔案轉化成html格式檢視
- 通過xslt工具轉化成html格式(儲存格式必須為xml格式)
-
Jmeter常用控制元件
-
測試計劃(Test Plan)
控制元件截圖:
理解:包含一個測試的所有內容,包含所有的控制元件,屬性,變數。所以一個jmx檔案中只有有一個測試計劃。測試計劃中可以定義變數,引入jar包,編輯測試模式等。
注意事項:
可將一些不常變化的資料存入測試計劃的變數,方便在測試計劃內呼叫(例如伺服器ip,埠,資料庫ip等)。
函式測試模式會記錄來每個請求到伺服器的取樣結果,如果在監聽器中定義了資料寫入檔案,會將這些輸入寫入到該檔案中。同時,該模式會嚴重影響效能。
-
工作臺
控制元件截圖:
理解:控制元件的暫存區域,在測試過程中可以把暫時不用的控制元件放入其中,待測試完成後放回原來的位置。
注意事項:工作臺中的控制元件不會儲存在jmx檔案中,所以,如果關閉jmeter,工作臺中的控制元件會丟失。
常用控制元件:
-
Property Display
- 建立方式:右鍵點選工作臺,新增——非測試元件——Property Display
- 截圖:
- 功能:檢視當前測試計劃中的屬性以及系統中的屬性
-
Property Display
-
執行緒組( Threads (Users)
)
理解:一個虛擬使用者組,執行緒組內執行緒數量在執行過程中不會發生改變。
注意事項:執行緒間變數相互獨立。一個測試計劃內可以包含多個執行緒組。
可定義內容:
取樣器錯誤後執行的操作:繼續執行,啟動下一個執行緒,停止執行緒,停止測試,立刻停止
執行緒屬性:執行緒數量,執行緒啟動間隔時間(0為立刻啟動所有執行緒),單執行緒迴圈次數,執行緒執行順序,是否使用排程器。
排程器配置:持續時間,啟動延遲,啟動時間,結束時間
-
執行緒組(Thread Group):
控制元件截圖:
理解:常規意義上的執行緒組,即虛擬使用者組。
-
SetUp Thread Group:
控制元件截圖:
理解:測試初始化操作,即執行緒組開始之前執行的內容。
實際使用:可用於初始化測試環境,測試資料準備等。
-
TearDown Thread Group:
控制元件截圖:
理解:測試執行後操作,即執行緒組執行完成後執行的內容。
實際使用:可用於清理測試環境,清空測試資料等。
-
執行緒組(Thread Group):
-
測試片段(Test Fragment)
- 理解:與執行緒組同級別,但是預設不會執行。只有當他被模組控制器引用的時候才會被執行。
- 控制元件截圖:
-
邏輯控制器(Logic Controller)
- 理解:用來控制取樣器的執行順序
-
分類:
- 控制取樣器的邏輯執行順序,如Loop Controller、If Controller等
- 對取樣器進行分組,方便控制的,如Throughput Controller、Transaction Controller
- 控制元件截圖:
-
常用控制元件:
-
簡單控制器(Simple Controller):
作用:這是Jmeter裡最簡單的一個控制器,它可以讓我們組織我們的取樣器和其它的邏輯控制器(分組功能),提供一個塊的結構和控制,並不具有任何的邏輯控制或執行時的功能。
-
迴圈控制器(Loop Controller):
作用:指定其子節點執行的次數,可以使用具體的數值(如下圖,設定為5次),也可以使用變數
1、Forever選項:勾選上這一項表示一直迴圈下去
2、如果同時設定了執行緒組的迴圈次數和迴圈控制器的迴圈次數,那迴圈控制器的子節點執行的次數為兩個數值相乘的結果。
-
僅一次控制器(Once Only Controller):
作用:在測試計劃執行期間,該控制器下的子結點對每個執行緒只執行一次,登入場景經常會使用到這個控制器。
注意:將Once Only Controller作為Loop Controller的子節點,Once Only Controller在每次迴圈的第一次迭代時均會被執行。
-
ForEach控制器(ForEach Controller):
作用:ForEach控制器一般和使用者自定義變數一起使用,其在使用者自定義變數中讀取一系列相關的變數。該控制器下的取樣器或控制器都會被執行一次或多次,每次讀取不同的變數值。如下圖:
引數:
- Input Variable Prefix:輸入變數字首
- Output variable name:輸出變數名稱
- Start index for loop(exclusive):迴圈開始的索引(這裡如果不填寫,預設從1開始,如果沒有1開始的變數,執行時會報錯)
- End index for loop(inclusive):迴圈結束的索引
- Add"_"before number:輸入變數名稱中是否使用"_"進行間隔。
使用者自定義變數:
變數名字首為ForEach Controller中Input variable prefix定義的name + 下劃線(上圖中我們勾選了下劃線)+數字編號
執行結果:
總共執行了3次,每次執行時會把獲取到的變數值賦值給輸出變數outNmae,其它地方可以通過${outNmae}進行呼叫。
-
事務控制器(Transaction Controller):
作用: 事務控制器會生產一個額外的取樣器,用來統計該控制器子結點的所有時間。
引數:
- Generate parent sample:(選中這個引數結果展示如下圖紅框,否則顯示為下圖藍框)
- Include duration of timer and pre-post processors in generated sample:選中這一項會統計定時器(timer)的時間,否則只統計取樣器(sample)的時間
-
If 控制器(If Controller):
作用:根據給定表示式的值決定是否執行該節點下的子節點,預設使用javascript的語法進行判斷(如下圖紅框內的文字)。
引數:
- Interpret Condition as Variable Expression?:選中這一項時表示:判斷變數值是否等於字串true(不區分大小寫)
- Evaluate for all children:如果選中這一項,在每個子結點執行前都會計算表示式
示例一:使用變數的方式進行判斷:
示例二:選中Interpret Condition as Variable Expression?
-
Switch控制器(Switch Controller):
作用:Switch控制器通過給該控制器中的Value賦值,來指定執行哪個取樣器。有兩種賦值方式:
- 第一種是數值,Switch控制器下的子節點從0開始計數,通過指定子節點所在的數值來確定執行哪個元素。
- 第二種是直接指定子元素的名稱,比如取樣器的Name來進行匹配。當指定的名稱不存在時,不執行任何元素。
當Value為空時,預設執行第1個子節點元素。
示例:
1、Switch Controller選擇的值為login page
2、執行結果:
-
吞吐量控制器(Throughput Controller):
作用:控制其下的子節點的執行次數與負載比例分配,也有兩種方式:
- Total Executions:設定執行次數
- Percent Executions:設定執行比例(1~100之間)
示例:
1、設定執行緒組迴圈5次:
2、Throughput Controller1的子結點執行3次:
3、Throughput Controller2的子結點執行(40% * 執行緒組迴圈次數5)= 2次:
執行結果:
-
隨機控制器(Random Controller):
作用:隨機執行其下的所某個子結點
-
隨機順序控制器(Random Order Controller):
作用:隨機執行其下的所有子結點
-
簡單控制器(Simple Controller):
-
配置元件(Config Element)
- 理解:為測試提供資料支援的控制元件
- 控制元件截圖:
-
常用控制元件:
-
CSV Data Set Config
理解:讀取txt,csv格式的測試資料
使用說明:
-
新建一個txt檔案
-
設定CVS 配置引數
-
CSV Data Set Config各個引數的簡要說明:
FileName:csv檔案或txt檔案路徑,可用相對路徑
File Encoding: 檔案編碼格式設定
Varible Names: 定義文字檔案中的引數名,可設定多個引數,引數之間逗號分隔.定義後可在指令碼中引用,引用方式${name}
Delimiter(use "\t" for tab):指定引數分隔符號
Allow Quoated data: 是否允許引用資料
Recycle on EOF: 是否迴圈取值
Stop Thread on EOF: 當Recycle on EOF為false並且Stop Thread on EOF為true,則讀完csv檔案中的記錄後,停止執行
Sharing Mode: 設定是否執行緒共享
使用場景:可用於多個jmx模組情況下讀取伺服器配置,或儲存id,賬號等測試資料。
-
新建一個txt檔案
-
HTTP Cookie管理器
特性:
1,象瀏覽器一樣的儲存和傳送Cookie。如果你請求一個站點,然後他的Response中包含Cookie,Cookie Manager就會自動地儲存這些Cookie並在所有後來發送到該站點的請求中使用這些Cookie的值。(在View Results Tree的Request介面可以看到被髮送的Cookie Data, 同時每個執行緒的Cookie Manager是相互獨立的)
接受到的Cookie的值能被儲存到JMeter 執行緒變數中(2.3.2版本後的JMeter不自動做這個事情)。要把Cookies儲存到執行緒變數中,要定義屬性"CookieManager.save.cookies=true"。
執行緒變數名為COOKIE_ + Cookie名。屬性CookieManager.name.prefix= 可以用來修改預設的COOKIE_的值。
2,手動新增Cookie到Cookie Manager,需求注意的是這些Cookie的值被會所有執行緒共享
定義:屬性"CookieManager.save.cookies=true"
在jmeter.properties檔案中增加CookieManager.save.cookies=true,然後在Debug Sampler中就能看到COOKIE_xxx這樣的變數,或者也可以使用正則表示式來提取Cookie的值
例項截圖:
使用注意事項:
路徑必須填寫,否則會導致nocookie
路徑和域組成完整的訪問地址,誰訪問誰就用對應的cookie
Cookie不是跨域的
不同的邏輯控制器中要分別放cookie管理器,或放在該cookie邏輯控制器同級,否則會不生效
-
HTTP資訊頭管理器
理解:定義資訊頭,在其覆蓋下的所有元件都會使用該資訊頭。例如定義在測試計劃中的資訊頭,即該測試計劃所有請求的資訊頭。
例項截圖:
-
JDBC Connection Configuration
理解:資料庫連線控制元件,不會進行的具體的資料庫操作。
例項截圖:
注意事項:
需要和JDBC Request配合使用
需要安裝jdbc驅動,否則無法連線資料庫
-
使用者定義的變數
理解:使用者自定義的變數,可用於儲存介面路徑等資訊
例項截圖:
注意事項:
注意變數的作用域,不同執行緒間變數不共享
-
CSV Data Set Config
-
定時器(Timer)
理解:sampler(取樣器)之前執行;如果只想應用於部分sampler,需要將定時器加入子節點;簡單理解類似於loadrunner中的思考時間,控制sampler的間隔時間。
控制元件截圖:
常用控制元件:
-
Constant Throughput Timer
理解:設定目標吞吐量,限定QPS的控制元件
例項截圖:
配置選項:
Target throughput(in samples per minute):目標吞吐量。注意這裡是每分鐘傳送的請求數,因此,對應測試需求中所要求的20 QPS ,這裡的值應該是1200 。
Calculate Throughput based on :有5個選項,分別是:
This thread only :控制每個執行緒的吞吐量,選擇這種模式時,總的吞吐量為設定的 target Throughput 乘以矣執行緒的數量。
All active threads : 設定的target Throughput 將分配在每個活躍執行緒上,每個活躍執行緒在上一次執行結束後等待合理的時間後再次執行。活躍執行緒指同一時刻同時執行的執行緒。
All active threads in current thread group :設定的target Throughput將分配在當前執行緒組的每一個活躍執行緒上,當測試計劃中只有一個執行緒組時,該選項和All active threads選項的效果完全相同。
All active threads (shared ):與All active threads 的選項基本相同,唯一的區別是,每個活躍執行緒都會在所有活躍執行緒上一次執行結束後等待合理的時間後再次執行。
All cative threads in current thread group (shared ):與All active threads in current thread group 基本相同,唯一的區別是,每個活躍執行緒都會在所有活躍執行緒的上一次執行結束後等待合理的時間後再次執行。
注意事項:
Constant Throughput Timer只有在執行緒組中的執行緒產生足夠多的request 的情況下才有意義,因此,即使設定了Constant Throughput Timer的值,也可能由於執行緒組中的執行緒數量不夠,或是定時器設定不合理等原因導致總體的QPS不能達到預期目標。
-
固定定時器
理解:請求間隔時間
例項截圖:
注意事項:
需要注意的是,固定定時器的延時不會計入單個sampler的響應時間,但會計入事務控制器的時間。
對於一個sampler來說,定時器相當於loadrunner中的pacing(理解就是一組請求操作的等待時間);對於"事務控制器"來說,定時器相當於loadrunner中的think time(單次操作的等待時間或間隔時間)
-
Constant Throughput Timer
-
高斯隨機定時器
理解:與固定定時器差不多,只不過時間範圍可以設定一個指定範圍隨機。
例項截圖:
-
Synchronizing Timer
理解:LR中的集合點,也就是說,sampler到這裡會暫停,達到指定執行緒數後併發
例項截圖:
配置引數:
Number of Simulated Users to Group by:執行緒數量設定
Timeout in milliseconds:響應時間設定,單位毫秒
注意事項:
集合點需要設定在Sampler前,否則不會生效
-
前置處理器(Per Processors)
理解:sampler請求前執行的操作,可以是獲取測試資料,修改引數等
控制元件截圖:
常用控制元件:
-
Bean Shell PreProcessor
理解:Bean Shell程式設計設定
例項截圖:
-
Bean Shell PreProcessor
-
Simpler Timeout:
理解:設定simple的最大響應時間,與直接在Sampler中設定的區別就是,作用域不同
控制元件截圖:
-
Sampler
理解:請求,設定不同的request
控制元件截圖:
常用控制元件:
-
HTTP請求
理解:就是一次HTTP請求
例項截圖:
-
Test Action
理解:請求的執行動作,可放在Sampler後定義,即執行某一個請求後暫停等操作
控制元件截圖:
-
HTTP請求
-
後置處理器(Post Processors)
理解:請求執行後的處理,與前置處理器相反
控制元件截圖:
常用控制元件:
-
正則表示式提取器
理解:當一個Sampler的Reponse中包含我們需要的引數的時候,我們可以通過該控制元件將引數提取出來
例項截圖:
引數含義:
引用名稱:將提取的引數轉化為變數,該欄位定義變數名稱
正則表示式:匹配的正則,測試可用搜索引擎搜尋線上正則驗證測試結果
-
正則表示式提取器
-
斷言(Assertions)
理解:判斷請求響應值的正確性的控制元件
控制元件截圖:
常用控制元件:
-
響應斷言:
理解:判斷Reponse是否正確
例項截圖:
注意事項:
斷言要放在請求內
-
響應斷言:
-
監聽器(Listener)
理解:檢視請求執行結果的控制元件
控制元件截圖:
常用控制元件:
-
圖形結果
控制元件截圖:
引數含義:
樣本數目:總共傳送到伺服器的請求數。
最新樣本:代表時間的數字,是伺服器響應最後一個請求的時間。
吞吐量:伺服器每分鐘處理的請求數。
平均值:總執行時間除以傳送到伺服器的請求數。
中間值:代表時間的數字,有一半的伺服器響應時間低於該值而另一半高於該值。
偏離:伺服器響應時間變化、離散程度測量值的大小,或者,換句話說,就是資料的分佈。
注意事項:圖形結果本身會影響Jmeter的效能
-
檢視結果樹
應用:可用於除錯,檢視請求響應的資料,測試的結果,請求的內容。
控制元件截圖:
引數含義:
取樣器結果例項:
請求例項截圖:
響應資料例項截圖:
-
聚合報告
理解:
控制元件截圖:
引數含義:
Label:每個 JMeter 的 element(例如 HTTP Request)都有一個 Name 屬性,這裡顯示的就是 Name 屬性的值
#Samples:表示你這次測試中一共發出了多少個請求,如果模擬10個使用者,每個使用者迭代10次,那麼這裡顯示100
Average:平均響應時間——預設情況下是單個 Request 的平均響應時間,當使用了 Transaction Controller 時,也可以以Transaction 為單位顯示平均響應時間
Median:中位數,也就是 50% 使用者的響應時間
90% Line:90% 使用者的響應時間
Min:最小響應時間
Max:最大響應時間
Error%:本次測試中出現錯誤的請求的數量/請求的總數
Throughput:吞吐量——預設情況下表示每秒完成的請求數(Request per Second),當使用了 Transaction Controller 時,也可以表示類似 LoadRunner 的 Transaction per Second 數
KB/Sec:每秒從伺服器端接收到的資料量,相當於LoadRunner中的Throughput/Sec
-
圖形結果
-
測試計劃(Test Plan)
-
Jmeter函式
-
函式助手
開啟位置:選項——函式助手
控制元件截圖:
函式例項:
${__time(YMD)}:當前日期函式
${__time(YMDHMS)}:當前四件函式
${__MD5(${fkeystr_no_register})}:MD5加密函式
更多可檢視函式助手的幫助頁面
-
函式呼叫
選擇想要使用的函式
輸入想要使用函式的值
點選生成
將所得字串複製到要使用的位置
-
函式助手
-
Jmeter屬性與變數
一、Jmeter中的屬性:
1、JMeter屬性統一定義在jmeter.properties檔案中,我們可以在該檔案中新增自定義的屬性
2、JMeter屬性在測試指令碼的任何地方都是可見的(全域性),通常被用來定義一些JMeter使用的預設值,可以用於線上程間傳遞資訊。
3、JMeter屬性可以在測試計劃中通過函式 _P 進行引用,但是不能作為特定執行緒的變數值。
4、JMeter屬性可以通過_setProperty 函式來定義JMeter屬性
5、JMeter屬性是大小寫敏感的
6、WorkBench中的屬性檢視元件:
WorkBench右鍵--->Add--->Non Test Elements--->Property Display
二、Jmeter中的變數:
1、JMeter變數對於測試執行緒而言是區域性變數。
2、在不同測試執行緒中,JMeter變數既可以是完全相同的,也可以是不同的。
3、JMeter變數引用方法:${name}
4、JMeter變數是大小寫敏感的
5、如果有某個執行緒更新了變數,那麼僅僅是更新了變數在該執行緒中複製的值
6、Jmeter中定義變數的地方:
a) 測試計劃(Test plan),在右邊的面板上新增User Defined Variables
b) 執行緒組,右鍵選擇 配置元件( config element)-->User Defined Variables
c) 通過前置或後置處理器生成的變數
d)使用csv引數化的變數
注意:通過 a 和 b 兩種方式定義的變數,在JMeter啟動時對這個測試計劃都是可見的。如果同一個變數在多個 b 中被定義,那麼只有最後一個定義會生效。一旦某個執行緒啟動後,那麼整個變數集合的初始值就會被複制到該執行緒中。其他測試元件,例如 c 或者 d 可以被用來重新定義變數,這些重定義僅僅影響當前執行緒
-
Jmeter錄製回放
-
BadBoy錄製回放
- 開啟badboy,點選錄製按鈕
- 輸入網址,在網頁中操作
- 匯出指令碼(File——Export to Jmeter)
- 用Jmeter開啟對應指令碼
-
BadBoy錄製回放
-
Jmeter使用
-
Jmeter建立介面測試計劃例項
測試用例應該作為測試的基礎內容,而用例的結構可能劃分,則是用例的基礎(忽然在這裡想說一下,用例僅僅是一項測試活動的綱要,有最好,沒有的話能保證質量也OK。更不用說用例的格式問題,無論是表格還是導圖,其實都無所謂!本文的用例是指jmx檔案中的控制元件結構)。
筆者在網上並沒有找到這方面的相關資料,所以沒有準確的定義說筆者的劃分是否是正確的或者合適的。筆者會闡明如此劃分的理由,但是大家實際使用過程中,僅僅作為拋磚引玉的一個磚頭而已。
- 模組名稱(測試計劃):每個模組獨立劃分為一個jmx檔案(例如登陸模組),最好與介面類一一對應。對應的伺服器資訊,資料庫資訊等可存在這裡。
- 資料準備:用於測試資料的準備(例如賬號資訊)。
- 結果檢視:用於放置需要檢視結果的控制元件(例如結果樹)。
- 執行緒組:所有的介面測試用例放線上程組下,集中定義執行緒等資訊
- 獲取執行緒對應測試資料:用於獲取針對獨立執行緒的測試資料,例如在資料準備裡面獲得了賬號資訊,在這裡根據賬號資訊去資料庫獲取對應的名稱,ID等資訊。
- 請求名稱:用簡單控制器為資料夾,內有不同的請求。簡單控制器為一個獨立的介面,不同請求對應不同的程式碼路徑(例如成功請求,失敗請求等)。建議請求名稱最好用英文形式,否則後期持續整合或許會出現問題(no zuo no die!)。
- 在每條請求內放置正則匹配(用於應對需要返回值作為下次請求的引數的情況)以及斷言。
-
Jmeter建立介面測試計劃例項
-
Jmeter使用注意事項
-
變數問題
使用過程中,一定要注意控制元件的執行順序以及變數的作用域。
-
路徑問題
Windows下支援"/""\"並存模式,推薦使用"/",方便跨平臺使用。
在linux格式下支援"/"格式。
-
Jmeter自身效能問題
命令列模式:命令相同。
UI模式:操作方式相同,但會存在windows下能開啟linux下打不開的情況,暫不知道原因。
-
變數問題
-
致謝
本文部分內容引用自網際網路上的優秀文章,感謝網路中願意分享的作者。可能本文中還涉及其他作者的文章未在下邊列出,如果有請聯絡我。
-
轉發自:部落格(測試散人:http://www.cnblogs.com/ceshisanren/p/5639895.html)