1. 任務需求
Postman壓測--------測試接口的穩定性
1.1.為什么要用postman進行測試
現如今,絕大多數項目,都采用前后端分離開發模式。
先是各自開發自己的部分,最后進行聯調。在開發中,希望提早發現問題,盡早解決。
所以,對於后端【服務端】開發,需要學會模擬客戶端調用,進而調試自己的代碼。
Postman就是模擬客戶端調用的常用工具。
1.2.postman如何進行壓力測試?
當你需要驗證你的接口的抗壓能力的時候,可以點擊Runner,進行壓力測試。
2.接口壓力測試相關概念
2.1.什么是壓力測試?
對項目中的一個HTTP接口進行壓力測試,以保證接口性能穩定性
預估的性能指標要達到200並發,500TPS。
在壓力測試過程中,我們重點關注TPS、GC次數、CPU占用率和接口響應時間等指標。
2.1.1.壓測指標有哪些?
》並發數
如:200並發,同時支持200個線程並發請求
》吞吐量TPS【】
》響應時間【請求到,返回結果所用時間】
壓力測試就是用來確保服務的穩定,給出服務穩定極限條件。穩定指的是服務負載,cpu利用率,接口的響應時長,網絡的延遲,結果准確性等等都在你的標准之內。而這些指標又相互影響。
每秒處理事務(TPS,Transaction Per Second) 每秒系統處理事務(通過、失敗以及停止)的數量。通過它可以確定系統在任何給定時刻的時間事務負載。
事務平均響應時間(Average Transaction Response Time) 每一事務執行所用的平均時間,通過它可以分析測試場景運行期間應用系統的性能走向。
• 最大響應時間(Max Response Time) 指用戶發出請求或者指令到系統做出反應(響應)的最大時間。
• 最少響應時間(Mininum ResponseTime) 指用戶發出請求或者指令到系統做出反應(響應)的最少時間。
• 90%響應時間(90% Response Time) 是指所有用戶的響應時間進行排序,第90%的響應時間。
CPU(CentralProcessing Unit) 中央處理器,是計算機的重要設備之一。功能主要是解釋計算機指令以及處理計算機軟件中的數據。
• CPU利用率(CPU Usage) CPU利用率分為用戶態,系統態和空閑態,分別表示CPU處於用戶態執行的時間,系統內核執行的時間,和空閑系統進程執行的時間。平時所說的CPU利用率是指:CPU執行非系統空閑進程的時間/CPU總的執行時間。
內存(Memory) 也被稱為內存儲器,其作用是用於暫時存放CPU中的運算數據,以及與硬盤等外部存儲器交換的數據。
• 內存使用率(Memory usage) 內存占用率指的是此進程所開銷的內存。
磁盤IO(Disk input/ output) 磁盤的讀寫包速率。
網卡負載(Network Load) 網卡的進出帶寬,包量。
其他指標
壓力測試:
壓力測試(Stress Testing)是通過確定一個系統的瓶頸或者不能接收的性能點,來獲得系統能提供的最大服務級別的測試
壓力強度(pressure intensity) 指壓力測試中對硬件的性能目標,比如系統的cpu利用率,內存使用率,磁盤I/O吞吐率,網絡吞吐量等所施加的條件。
並發(Concurrent) 在操作系統中,指一個時間段中有幾個程序都處於已啟動運行到運行完畢之間,且這幾個程序都是在同一個處理機上運行,但任一個時刻點上只有一個程序在處理機上運行。
並發用戶數(the number of concurrent users ) 在同一時刻與服務器進行了交互的在線用戶數量。
最大並發數(Maximum number of concurrent users) 指同時登錄站點的最大人數或者服務器同時接收下載的最大數量。
負載測試
核實在保持配置不變的情況下,測試對象在不同操作條件(如不同用戶數、事務數等)下性能行為的可接受性。
請求訪問數量(VU 或RequestThread) 指發送請求壓力的數量
HTTP錯誤率(HTTP error rate) 在選定時間段內,HTTP錯誤數量與請求數量的比率。
吞吐率(Throughput) 是場景運行過程中服務器每秒的吞吐量。其度量單位是字節,表示每個請求連接在任何給定的每一秒從服務器獲得的數據量。
系統性能監控
事務(Transactions) 事務是用戶某一步或幾步操作的集合。
3.postman進行接口壓力測試
3.1.postman設置環境變量/全局變量
1.切換環境變量窗口
2.查看環境變量
3.設置環境變量
3.2.為什么要設置環境變量?
原因1:為了方便切換不同環境。
原因2:為了變量傳值。
如果接口1-----
會產生一個json串,如下所示:
{
"errorMsg": "",
"instanceId": "instance-52886563",
"trackUrl": ""
}
現在,下一個接口需要獲取instanceId的值,傳入接口中,獲取值
為了自動化測試,把變量值放到變量中,進行傳值。如下所示:
{{url}}/{{instanceId}}/state?userId=admin&accessId=cyj&accessKey=ak2&tenantId=antTenantId&db=default_dev
3.3.接口測試使用全局變量
3.3.1.原始接口
通過Tests測試腳本,獲取接口返回值存入環境變量中。
Tests腳本如下:
pm.test("Status code is 200", function () {
var jsonData = JSON.parse(responseBody);
pm.environment.set("instanceId",jsonData.instanceId);
});
Json數據格式如下:
{
"errorMsg": "",
"instanceId": "instance-52886566",
"trackUrl": ""
}
3.3.2.依賴接口
后一接口,需要調用上一接口的返回值作為參數。
同時需要在http請求頁,切換環境變量。
4.jmeter進行壓測
4.1.測試目標
》接口響應時間
》接口響應結果正確性
4.2.jmeter測試案例
4.2.1.環境准備
注意:jmeter依賴jdk【個人使用jdk8】
》下載jmeter【apache工具】
》安裝jmeter
下載zip文件,解壓到安裝目錄,直接找到jmeter.bat文件【即可啟動jmeter】
4.2.2.jemter測試post請求【url+json傳參,返回json】
測試接口:
body傳參:
{
"appName": "dsg-sampling",
"type": "batchsql",
"commandText": "use datago_dev;select * from two_partitioned_by_time;",
"priority": 2,
"params": {}
}
4.2.2.1.創建測試計划
當打開jmeter時,默認會根據template創建一個Test Plan.
先對測試計划進行保存--------選擇一個目錄-----文件名:demo_sdk.jmx
1.創建線程組
三個重要的參數:
Number Of Threads:線程數【並發用戶】,模擬用戶
Ramp-up Period:運行周期,如:1秒鍾
Loop Count:請求次數
線程數是500,就是相當於有500個用戶,運行線程的總時間是1秒。也就是說在這1秒中之內100個用戶同時訪問,每個用戶循環一次,也就是訪問一次。
2.線程組創建默認Http
設置ip,端口號,編碼:
3.創建請求頭header
因為需要傳參json,設置:Content-Type=application/json;charset=UTF
然后,點擊save,進行保存。
4.設置http
注意:
當url中帶有參數時,直接放到path中。
Json數據:放在bodyData中
5.創建結果報告【可以在線程組和http下創建】
一般在http上add.
目的是:展示接口響應結果,是否正確?
添加結果如下:
6.線程組下添加聚合報告【查看壓測相關指標】
如:響應時間,錯誤率,吞吐量。。。
說明:一般在線程組下進行添加,只有點擊運行,就會讓所有http都運行result report.
通過表格,展示壓測指標:
Average:平均響應時間
Min:最小響應時間
Max:最大響應時間
這個表格數據:匯總所有的http接口----同時,還可以導出表格數據【】
4.3.測試get請求
4.4.jmeter+bean shell斷言驗證
4.4.1.為什么要用bean shell斷言
使用jmeter測試http接口,需要自動化驗證接口返回結果是否符合我們的預期。
原來通過View Result Tree只能手動查看一個個接口,如下所示:
現在,我希望並發執行多個請求時,通過代碼【斷言】統一輸出運行結果:
》有多少運行成功
》response code為200,但返回數據不符合預期
》response code 為200,返回數據也符合預期。
》有多少運行失敗
》直接響應碼不是200,明顯報錯。
這個目的,可能bean shell斷言插件【工具】來達到目的。
4.4.2.bean shell使用
Bean shell主要用來驗證json數據是否符合預期。需要引入jmeter依賴json的jar包。
預期json:
{
"errorMsg": "",
"instanceId": "instance-52891107",
"trackUrl": ""
}
4.4.2.1.引入json依賴包
【下載json依賴包】
由於要解析json,那么就需要用到json相關的jar依賴包,下載地址:
http://download.csdn.net/download/xiaoxiao_renhe/10246640
如下所示:
4.4.2.2.【准備工作就緒,開工】
1.首先運行Jmeter(可以直接運行\apache-jmeter-3.0\bin下的jmeter.bat或在CMD直接輸入jmeter然后回車)
2. 創建jmeter測試計划
3.導入json依賴包
1.在"...apache-jmeter-3.0\bin"目錄下新建dependencies文件夾,並將剛才下載下來的json依賴包(json-20140107.jar)復制進去,如下所示:
2.打開"...apache-jmeter-3.0\bin"目錄下的jmeter.properties配置文件,搜索"plugin_dependency_paths=",刪除該行的注釋並設置為plugin_dependency_paths=../dependencies,最后保存;至此配置成功,在JMeter的BeanShell PostProcessor里就可以正常引用jar依賴包了。
3.不知道為什么有時候通過上述方法仍無法正常引用外部jar包,那么為了以防萬一,強烈建議在測試計划中通過瀏覽將需要導入的jar包引入,如下所示:
4.4.2.3.http請求下添加bean shell斷言
然后,編寫腳本:
4.4.2.3.1.編寫測試腳本
import org.json.*;
//獲取請求的返回code碼
String responseCode = prev.getResponseCode().toString();
if(!"200".equals(responseCode)){
Failure = true;
FailureMessage = "創建實例接口,響應失敗,響應code為:"+responseCode;
return;
}
String response = prev.getResponseDataAsString().toString();
JSONObject responseJson = new JSONObject(response);
//解析json對象
String message = responseJson.getString("errorMsg").toString();
if("null".equals(message) || "".equals(message)){
Failure = false;
FailureMessage = "創建實例接口,響應成功,測試通過";
String instanceId = responseJson.getString("instanceId");
log.info("instanceId的值:" + instanceId);
return;
}else{
Failure = true;
FailureMessage = "創建實例接口,響應失敗";
log.info("message的值:" + message);
return;
}
》判斷response code是否200
》如果不是,直接斷言失敗,返回code
》如果是,獲取json數據,解析json,驗證是否符合預期
String response = prev.getResponseDataAsString().toString(); //獲取上一個請求返回數據
JSONObject
= new JSONObject(response);
Prev:是jmeter內置對象
預期json:
{
"errorMsg": "",
"instanceId": "instance-52891107",
"trackUrl": ""
}
通過key:value形式獲取value值,如:獲取errorMsg,使用
String message = responseJson.getString("errorMsg").toString();
說明:
當符合預期時,設置
Failure = false; //表示斷言成功,通過測試
FailureMessage = "創建實例接口,響應成功,測試通過"; //設置成功輸出信息【只有當Failure設置為true時,才會打印出,實際意義不大】
當斷言報錯時,jmeter會當作接口請求失敗,veiw result tree中展示報錯,如下所示:
4.4.2.4.添加斷言結果報告
輸出結果如下:
4.4.3.測試第二個接口
4.4.3.1.期望json數據
正確結果:
報錯:實例不存在
{
"createTime": "",
"endTime": "",
"errorMsg": "NoSuchObjectException: 52886314",
"exitCode": -1,
"startTime": "",
"state": "",
"trackUrl": ""
}
2.state結果不為Success
{
"createTime": "1577949384000",
"endTime": "1577949462971",
"errorMsg": "",
"exitCode": 211,
"startTime": "1577949404306",
"state": "FAILED",
"trackUrl": "http://yarn-master-1:8088/proxy/application_1576845881305_2841/"
}
{
"createTime": "1578387559000",
"endTime": "",
"errorMsg": "",
"exitCode": -1,
"startTime": "",
"state": "PENDING",
"trackUrl": "http://yarn-master-1:8088/proxy/application_1576845881305_37367/"
}
4.4.3.2.shell 腳本
import org.json.*;
//獲取請求的返回code碼
String responseCode = prev.getResponseCode().toString();
if(!"200".equals(responseCode)){
Failure = true;
FailureMessage = "創建實例接口,響應失敗,響應code為:"+responseCode;
return;
}
String response = prev.getResponseDataAsString().toString();
JSONObject responseJson = new JSONObject(response);
//解析json對象
String message = responseJson.getString("errorMsg").toString();
String state = responseJson.getString("state").toString();
if(("null".equals(message) || "".equals(message)) &&”SUCCESS”.equals(state) ){
Failure = false;
FailureMessage = "創建實例接口,響應成功,測試通過";
String instanceId = responseJson.getString("instanceId");
log.info("instanceId的值:" + instanceId);
return;
}else{
Failure = true;
FailureMessage = "創建實例接口,響應失敗,狀態為:"+ state;
log.info("message的值:" + message);
return;
}