Jmeter使用筆記(本文偏"介面測試工具")【GET/POST的HTTP請求、請求頭、響應斷言、正則表示式提取器、CSV讀取引數、跨執行緒組傳遞變數】
一、執行一個HTTP請求
自從畢業從事軟體測試行業,大多數時間都在跟各種API打交道,使用過的介面測試工具也有許多,本文記錄下各工具的使用心得,以及重點介紹我在工作中是如何使用Jmeter做測試的,都是在windows作業系統下進行。
最開始使用postman,該工具的優點是可以儲存測試過程中使用的請求資料,可以把被測系統中所有的介面請求都儲存在該工具中,對於排查定位問題,該工具還是很好用的,缺點就是效率太低,碰到一個業務流程涉及執行多個介面時,手動填引數實在慢。
一、安裝Jmeter
1.JAVA環境
JDK下載地址http://java.sun.com/javase/downloads/index.jsp
配置系統變數:
(1)JAVA_HOME,變數值為:你在本地安裝JDK的目錄。
C:\Program Files\Java\jdk1.6.0_10;
(2)CLASSPATH,變數值為:
C:\Program Files\Java\jdk1.6.0_10\lib\dt.JAR; C:\Program Files\Java\jdk1.6.0_10\lib\TOOLS.JAR; C:\Program Files\Java\jdk1.6.0_10\BIN;
(3)修改PATH變數
新增C:\Program Files\Java\jdk1.6.0_10\bin;
檢測JDK安裝是否成功:執行-->CMD-->輸入"java",如果能看到幫助資訊說明JDK安裝成功。
2.JMETER環境
下載地址:http://jmeter.apache.org/download_jmeter.cgi
解壓apache-jmeter-2.11.zip到本地(任何目錄均可),比如我把它下載到:“E:\Jmeter\apache-jmeter-2.3.4”。
配置系統變數:
(1)JMETER_HOME,變數值為:
E:\Jmeter\apache-jmeter-2.3.4
(2)修改CLASSPATH變數
新增%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;% JMETER_HOME%\lib\jorphan.jar;%JMETER_HOME%\lib\logkit-1.2.jar;
JMeter外掛安裝
2. 外掛下載後解壓:找到JMeterPlugins-Extras.jar,把JMeterPlugins-Extras.jar放到apache-jmeter-2.12\lib\ext目錄。
執行方式:點選Jmeter目錄下bin資料夾裡的jmeter.bat就可以開啟Jmeter。
二、執行一個HTTP請求
1.新增一個執行緒組
執行緒屬性{Ramp-Up Period(in seconds)}:意味著這個執行緒內的所有執行緒(對我來說是http請求)在多久時間內執行完畢,值為0,意味著併發執行執行緒組下的所有請求。
2.新增一個HTTP請求
“執行緒組”右鍵->新增->Sampler->HTTP請求
3.新增“察看結果樹”
“執行緒組”右鍵->新增->監聽器->檢視結果樹
4.執行
二:GET/POST請求引數填寫
舉例來說
我的被測系統API的http請求涉及到GET/POST/PUT/DELETE四種。請求傳參可分為兩種:
GET請求
1 | http: //請求路徑/Ecs-duHc0U4E #該請求引數“Ecs-duHc0U4”以斜槓形式傳入 |
POST請求
1 | http: //請求路徑?subnetCode=Subnet-tQSPwlp1&imageCode=image-djcgebxfd #該請求引數subnetCode和imageCode以問號形式傳入 |
區別是:
第一種解析的時候會把後面的字元當做路徑或是地址;
第二種解析的時候會把後面的地址當做匹配關鍵字,“?”起連線作用,表示要帶引數,“&”作為不同引數的間隔符。
Jmeter中的請求方式
1、GET請求
在察看結果樹中看到完整的請求路徑是:http://10.10.28.131:8080/middleware/v2/ecs/Ecs-do93KwLL
2、POST請求
在察看結果樹中看到完整的請求路徑是:http://10.10.28.131:8080/middleware/v2/ecs/power/stop?ecsCode=Ecs-AwDrEYdx
三:管理請求伺服器資訊和Headers引數
如果使用Jmeter同時執行多個http請求任務,就需要建立多個HTTP取樣器,每一個取樣器都來手動填寫伺服器資訊和埠號,會非常消耗時間。
解決方法:Jmeter之HTTP請求預設值
1、新增方式
“執行緒”右鍵->新增->配置元件->選中HTTP請求預設值
2、配置好伺服器IP和埠以後,新建一個HTTP取樣器,不填寫伺服器資訊。
3、執行,檢查結果。
可以看出該配置元件是作用於整個執行緒內的,對該執行緒內的所有HTTP請求都生效。
引數列表:
Attribute | Description | Required |
Name | 元件名 | No |
Server | 域名或IP | No |
Port | 埠 | No |
Connect Timeout | 連線超時時間(單位毫秒) | No |
Response Timeout | 響應超時時間(單位毫秒) | No |
Implementation | 實現方式,預設值為Jmeter屬性:jemter.httpsampler | No |
Protocol | 協議,HTTP or HTTPS | No |
Method | 請求方法:HTTP GET or HTTP POST | No |
Path | 請求資源路徑 | No |
Send Parameters With the Request | 引數列表 | No |
Server (proxy) | 代理伺服器的域名或IP | No |
Port | 代理伺服器的埠 | No, unless proxy hostname is specified |
Username | 代理伺服器的使用者名稱 | No |
Password | 代理伺服器的密碼 | No |
Retrieve All Embedded Resources from HTML Files | 告訴Jmeter解析HTML檔案併發送所有資源請求(包括圖片,java小程式,JS,CSS等) | No |
Use concurrent pool | 用一個連線池來獲取嵌入的資源 | No |
Size | 用於獲取嵌入式資源的併發連線池大小 | No |
Embedded URLs must match: | URL匹配,過濾 | No |
我的被測系統中Headers需要填寫引數,該引數作為使用者唯一識別符號,請求傳入了它伺服器才會對請求作出響應。
Jmeter之HTTP資訊頭管理器
1、新增方式
“執行緒”右鍵->新增->配置元件->選中HTTP資訊頭管理器
2、執行一個請求,檢視請求資料
可以看出請求中的headers已經傳入我所填寫的引數accessKey,並且該配置元件同樣作用於該執行緒內所有請求。
四:響應斷言
Jmeter中斷言的型別有許多,我不在這裡一一列舉,只說下我用到的---響應斷言。
作用:一個HTTP請求發出去,怎麼判斷執行的任務是否成功呢?通過檢查伺服器響應資料,是否返回預期想要的資料,如果是,判斷任務成功,反之任務失敗。
1、新增方式
選中一個取樣器,右鍵->新增->斷言->選中“響應斷言”
(1)Apply to
關於應用範圍,我們大多數勾選“main sample only” 就足夠了,因為我們一個請求,實質上只有一個請求。但是當我們發一個請求時,可以觸發多個伺服器請求,就有main sample 和 sub-sample之分了。
(2)要測試的響應欄位
勾選“響應文字”,會在響應資料中進行校驗。
(3)匹配規則
勾選“包括”,意味著只要相應資料中包含要校驗的欄位,任務就算成功。
(4)要測試的模式
即需要校驗的資料值。
2、檢視執行結果
(1)失敗的任務
判斷為任務失敗,檢視結果樹任務結果顏色標紅。
(2)成功的任務
判斷為任務成功,檢視結果樹任務結果顏色標綠。
五:正則表示式提取器
(正則表示式提取器是Jmeter關聯中的一種)使用場景:
有兩個HTTP請求,請求A的返回資料中有一個欄位“ABCD”,該欄位要作為請求B的入參。
1、新增方式
請求A上右鍵-->後置處理器->正則表示式提取器
2、提取A請求中的taskCode對應的值
為了獲取到上圖中圈起來的這個值,要配置正則表示式提取器:
說明:
(1)引用名稱:下一個請求要引用的引數名稱,如填寫Atask,則可用${Atask}引用它。
(2)正則表示式:
():括起來的部分就是要提取的。
.:匹配任何字串。 +:一次或多次。 ?:不要太貪婪,在找到第一個匹配項後停止。(3)模板:用$$引用起來,如果在正則表示式中有多個正則表示式,則可以是$2$$3$等等,表示解析到的第幾個值給title。如:$1$表示解析到的第1個值
(4)匹配數字:0代表隨機取值,1代表全部取值,通常情況下填0
(5)預設值:如果引數沒有取得到值,那預設給一個值讓它取,我填的Error。
3、獲取到的值傳入B請求
看一下請求B是否如預期的一樣傳入Atask這個值
引用成功~~
記錄一個好用的測試正則表示式的工具:
工具名稱:RegexTester
使用方法:
六:從文字讀取引數
使用場景:測試一個介面併發處理資料的能力,並且每次請求傳入的引數都要不同。
解決方法--- CSV Data Set Config
列舉一個例項,步驟中會側重讀取引數操作的說明,其他有疑問的步驟請查閱博主之前Jmeter相關的文章。
1、建立HTTP請求預設值---為了指定請求的伺服器資訊
2、建立HTTP資訊頭管理器---為了在Headers中傳值
3、建立HTTP取樣器---我們的請求任務
填好Http請求方式和請求路徑,請求引數用變數方式引用進來,變數來源於CSV Data Set Config配置:
(1)新增CSV Data Set Config
(2)配置CSV Data Set Config
- Filename:需要傳入的引數所位於的檔名稱,一定要填寫完整路徑,博主填寫的絕對路徑。
- File encoding:引數檔案的編碼格式。可以不填。
- Variable Names:對應引數檔案中每列的變數名,也是你要引用到請求中的引數變數名。例如博主填寫的值為ecsCode,在http請求中引用該引數時${ecsCode}
- Delimiter:檔案中的分隔符,一般用英文的逗號分隔開即可。
- Allow quoted data?:是否允許引用資料。博主沒有用到,預設設定為 false。
- Recycle on EOF?:是否迴圈讀取引數檔案內容。設定為 true 時,意味著已經讀取完引數檔案內的測試用例資料時,執行緒迴圈次數仍然沒有結束,那就迴圈讀取引數檔案資料;設定為 false 時,若已至檔案末尾,則不再繼續讀取測試資料。
- Sotp thread on EOF?:當讀取到引數檔案末尾時,是否停止讀取執行緒。預設為 false。當 Recycle on EOF? 設定為 true 時,此項不起任何作用。當且僅當 Recycle on EOF? 為 false 時,此項配置才生效。
- Sharing mode:共享模式,即引數檔案變數作用域,博主沒用到就不關注他。
(3)在文字中填寫引數
- 該檔案所在的路徑即為CSV Data Set Config配置元件中的Filename值;
- 博主只傳入一個引數,所以只有一列,如果有兩個引數,會有兩列資料,並用英文逗號隔開;引用引數時,CSV Data Set Config配置元件中Variable Names填寫兩個變數,也用英文逗號隔開即可
- 有10行資料,意味著10條測試用例,我會設定執行緒迴圈10次。這也是為什麼我會在CSV Data Set Config配置元件中Recycle on EOF填寫False
迴圈次數設定為10,意味著該條請求只執行10次。
Ramp-Up Period設定為0,意味著10條請求同時發出。如果設定為5,意味著5秒內發起10條請求,平均1秒發出2條。
(4)在請求中引用引數
4、增加一個響應斷言,意味著返回資料包含“執行成功”字樣,任務成功
5、新增監聽器-察看結果樹
測試得知,按照預期取到了值~
七:使用者定義的變數
使用場景:一組API根據業務流程製作成測試指令碼,想要移植到其他測試環境時,由於資料庫發生了變更,有些初始化資料也相應發生了變化,例如環境地址、請求路徑等等。博主甚至把伺服器地址和介面的部分共同請求路徑都做成了自定義變數。
1、新增方式
執行緒組 右鍵->新增->配置元件->使用者定義的變數
2、作用範圍
當前的執行緒組內所有取樣器(即博主的HTTP請求)都可以引用變數
3、變數引用方式
需要說明的是,伺服器IP地址和埠號以及介面共同的請求路徑部分,作為變數引用時,需要在路徑填充表格的最前面新增兩個斜槓“//”,不加的話會引用失敗。
八:模擬OAuth2.0協議簡化模式的請求
背景
博主的主要工作是測試API,目前已經用Jmeter+Jenkins實現了專案中的介面自動化測試流程。但是馬上要接手的專案,API應用的是OAuth2.0協議授權,並且採用的是簡化模式(implicit grant type)。所以最近學習了一下該協議,並嘗試用Jmeter模擬該授權方式的處理流程,以改進自動化測試指令碼。
本文主要分為三個部分:1、簡述OAuth2.0協議中的簡化模式授權方式;
2、通過在瀏覽器上抓包,分析獲取授權的過程中經歷了什麼;
3、嘗試用Jmeter模擬整個授權過程,獲取授權令牌。
一、OAuth2.0協議簡述
OAuth 2.0定義了四種授權方式。博主這裡只介紹簡化模式。有興趣瞭解該協議全部內容的同學可以參考本文末的參考文章。
授權過程中參與的四種角色:
- 資源所有者(Resource Owner):對資源具有授權能力的人。即使用者。
- 第三方應用(Client):獲得資源所有者的授權後,就可以去訪問資源所有者的資源。
- 資源伺服器(Resource Server):儲存資源,並處理對資源的訪問請求。
- 授權伺服器(Authorization Server):它認證資源所有者的身份,為資源所有者提供授權審批流程,並最終頒發授權令牌(Access Token)。
請注意,為了便於協議的描述,這裡只是在邏輯上把授權伺服器與資源伺服器區分開來;在物理上,AS與RS的功能可以由同一個伺服器來提供服務。
簡化模式的基本工作流程如下:使用者被請求授權應用程式,然後授權伺服器將訪問令牌傳遞迴使用者代理,使用者代理將其傳遞給應用程式。
Step 1: Implicit Authorization Link
使用簡化模式授權型別,使用者會得到一個授權連結,它會從API來請求獲取令牌(即:token)。授權連結如下所示:
http://10.10.28.141:9999/uaa/oauth/authorize?response_type=token&client_id=cmop&redirect_uri=http://example.com
對授權連結的各部分介紹:
http://10.10.28.141:9999/uaa/oauth/authorize:API授權端點
client_id=cmop:應用程式的客戶端ID(API用來標識應用程式)
redirect_uri=http://example.com:當令牌頒發之後,認證伺服器把使用者導向客戶端指定的重定向URI
response_type=token:表示授權型別,固定值為token,表示請求授權令牌
Step 2: User Authorizes Application
當用戶點選這個連結時,首先要登入到伺服器驗證身份(除非已經登入過),然後伺服器會提示使用者進行授權或拒絕第三方應用使用他們的賬戶。
Step 3: User-agent Receives Access Token with Redirect URI
如果使用者同意授權,授權伺服器將使用者導向客戶端指定的“重定向URI”,並在其中攜帶一個包含訪問令牌的URI片段,看起來像這樣:
http://example.com/#access_token=b8c512ef-8083-4654-b71b-7bbe85b03d8d&token_type=bearer&expires_in=19062&scope=open
對重定向URI的各部分介紹:
access_token:表示訪問令牌
token_type:表示令牌型別,該值大小寫不敏感,必選項,可以是bearer型別或mac型別
expires_in:表示過期時間,單位為秒
scope:表示許可權範圍
好了,後面提取令牌以及把令牌發回給應用程式的步驟就不展開了,我們只要瞭解到如何獲取到授權令牌就可以了,接下來訪問伺服器資源的時候,在請求API的requests中帶入令牌引數即可。
二、瀏覽器抓包過程
1、在瀏覽器中使用授權連結發起申請令牌請求
http://10.10.28.141:9999/uaa/oauth/authorize?response_type=token&client_id=cmop&redirect_uri=http://example.com
(1)Firefox瀏覽器,開啟Firebug,輸入授權連結發起請求,如下圖:
從圖上可看出,我發起請求後,抓到6條GET請求,前兩條是我們需要關注分析的資料,後面四條都是在請求頁面元素所以不做關注:
- 第一條請求:GET請求授權連結,返回狀態碼為302,表示請求連結被暫時性重定向;
- 第二條請求:GET請求暫時性重定向的連結,即跳轉到目前的頁面,其URL為http://10.10.28.141:9999/uaa/login.html
(2)接下來我們看一下前兩條requests中的具體資訊,如下圖:
從圖上可以看出,發起第一個GET請求(即授權連結),在其響應頭資訊(Response Headers)中的Location欄位標明瞭接下來瀏覽器將重定向的地址;而且還在其中返回一個Set-Cookie欄位;
再來看第二個請求,他的請求頭資訊(Request Headers)中包含一個引數Cookie,該值與上面的Set-Cookie欄位的值相同。
注意:我們把這裡的Set-Cookie和Cookie的值起個名字,叫做JSESSIONID_1,方便和後面的cookie值進行區分。
2、使用者同意進行授權操作
http://10.10.28.141:9999/uaa/login.html
(1)在前一步的操作中,我們進行到瀏覽器跳轉到暫時性重定向的頁面,等待使用者輸入賬號密碼驗證身份,然後進行授權。
我們首先輸入正確的使用者名稱密碼,通過驗證,檢視瀏覽器會發出什麼請求:
從圖上可看出,我在輸入使用者名稱密碼後,抓到3條請求,並且瀏覽器跳轉到指定的重定向URI,而且可以在該連結中看到伺服器返回來的access_token引數:
- 第一條請求:POST請求,向伺服器提供使用者名稱密碼引數,伺服器驗證使用者身份通過後,跳轉回申請授權連結;
- 第二條請求:GET請求,再次向伺服器請求申請授權令牌(此時已經得到使用者的授權),伺服器會頒發令牌,認證伺服器把使用者導向客戶端指定的重定向URI;
- 第三條請求:GET請求,重定向的URI,並且其中包括訪問令牌access_token
(2)接下來我們看一下request中的具體資訊:
- POST請求:請求頭資訊中傳入的cookie引數,與第一個步驟中獲取的JSESSIONID_1值一模一樣。響應頭資訊中返回的Set-Cookie值記錄為JSESSIONID_2;
- 第一個GET請求:再次跳轉到授權連結向伺服器發起請求,此時請求頭資訊中傳入的Cookie引數是JSESSIONID_2,響應頭資訊中的Location欄位包含令牌;
- 第二個GET請求:我沒有截他的圖,因為他只是最終認證伺服器把使用者導向的重定向URI。而我們已經拿到token的資料了。
總結:從使用者在瀏覽器輸入授權連結到最後瀏覽器返回給我們access_token的過程中,由於其中包含暫時性重定向的地址,所以瀏覽器自動進行過很多跳轉。需要我注意的只有兩個請求,第一個是GET請求授權連結,瀏覽器會自動跳轉到使用者身份驗證頁面,並儲存一個cookie(我叫它驗證cookie);第二個就是POST請求使用者認證連線,傳入使用者名稱和密碼引數,並帶入驗證cookie,伺服器驗證使用者身份後再返回另一個cookie(我叫它授權cookie),也儲存在瀏覽器中,然後自動跳轉到授權連結,此時傳入授權cookie,伺服器即頒發正確的令牌給使用者~~