BeanShell腳本--編寫【請求失敗觸發報警郵件】功能
一、需求背景
一個內容簡單的常規接口請求壓力測試,每秒需要10個請求,持續2~3天。因此無人隨時監控,需要一個報警郵件機制。
特別說明:我在網上查找了很久,沒有發現Jmeter就有請求失敗就報警的功能或者插件,因此自己編寫(原創,嘎嘎),如果有誰知道類似的插件,請給我留言,萬分感謝。
二、工具選用
Jmeter,工具本身不帶有郵件報警功能,需要自己編寫BeanShell腳本在接到響應之后進行處理,BSH斷言或者BSH后置處理器都行;
三、最終結構目錄預覽

四、設計思路
1、觸發條件設計:由於是大批量,長時間的壓測,如果出現錯誤必然是成批出現,則不可能出現一個請求失敗就發送一個報警郵件,因此設計一個觸發閾值,每次觸發后閾值歸零進入下一次統計。
2、根據響應的結果需要對code和msg進行同時校驗。
3、利用if控制器的判斷條件來執行是否發送報警郵件。
4、報警郵件中包含 時間,請求信息,響應等信息。
五、腳本編寫及變量設置
1、
預設置全局變量6個

errcount:用於記錄請求錯誤次數,其中:數字“0”為每次壓測執行時需要恢復的默認初始值;
sendemail:是否發送報警郵件的標識,默認初始值是字符串“no”,當值為"yes"時,發送郵件(if邏輯控制器執行);
Reqstauts:由於利用響應代碼和響應信息聯合做判斷,所以需要此變量標識請求是否成功。默認值“requestok”,如果值為“requestNook”則表示請求失敗,errcount+=1。
respcode:由於郵件中需要引入響應代碼,因此設置此參數。
respmsg:由於郵件中需要引入響應信息,因此設置此參數。
respdata:由於郵件中需要引入響應數據,因此設置此參數。
2、采樣器BeanShell斷言腳本

2.1、根據請求的響應結果(返回碼+返回消息)判斷請求是否成功
【響應斷言--msg=SUCCESS】頁面參數配置:Main Sample only+響應文本+匹配+要測試的模式:"SUCCESS"
【響應斷言--code=200】頁面參數配置:Main Sample only+響應代碼+Equals+要測試的模式:"200"
if(!(SampleResult.getResponseCode().equals("200") && SampleResult.getResponseDataAsString().equals("SUCCESS")))
{
XXXXXXX;
}
2.2、請求失敗則獲取響應代碼,信息,數據並變更對應的全局變量的值
//獲取響應中的響應參數
String code = SampleResult.getResponseCode();
String msg = SampleResult.getResponseMessage();
String data = SampleResult.getResponseDataAsString();
//調試時的打印信息,正式測試時應該注釋掉下面3行log.error();
log.error("-----------Returncode is :\"" + code + "\"");
log.error("-----------ResponseMessage is :\"" + msg + "\"");
log.error("-----------ResponseData is :\"" + data + "\"");
//將響應的參數賦值給對應的全局變量,用於后續郵件中使用
vars.put("respcode",code);
vars.put("respmsg",msg);
vars.put("respdata",data);
vars.put("Reqstatus","requestNook");
2.3、設置請求結果標識為失敗,請求失敗計數器加1
vars.put("Reqstatus","requestNook");
count =count + 1;
vars.put("errcount",count.toString());
log.error("----False------count="+count);
2.4、根據閾值是否觸發報警郵件
if((count % 3) == 0){
//sendemail=yes則if邏輯控制器會觸發發送報警郵件
vars.put("sendemail","yes");
log.error("--------It is sendemail ? :"+vars.get("sendemail"));
}else{
vars.put("sendemail","no");
}
//設置當前請求采樣器Sampler為失敗狀態(查看結果樹里紅色高亮顯示)
SampleResult.setSuccessful(false);
3、IF控制器及郵件發送采樣器

3.1、IF控制器
由於需要根據條件來判斷是否需要發送郵件,因此選擇了IF控制器
"${sendemail}"=="yes" 是否發送郵件的標識變量sendemail等於yes時,發送郵件。
標識變更在斷言【BSH斷言--10000次錯誤則發送報警郵件】中進行設置

3.2、SMTP郵件采樣器配置


郵件標題:【eagleeye接口請求失敗${__time(YMD)}--${__time(HMS)}】其中后半部分“${__time(YMD)}--${__time(HMS)}”是Jmeter內置變量,在請求成功發送出去后,結果會顯示成類似“20170221--135323”形式
郵件內容:
Returncode is :${respcode} <-----響應代碼
ResponseMessage is :${respmsg} <----響應信息
ResponseData is :${respdata} <----響應數據
說明一下:最后是使用sina郵箱成功發送郵件。因為126郵箱盡管設置了【客戶端授權密碼】,使用Firefox發送郵件,但Jmeter的郵件代理發送仍然失敗。有熱心朋友提醒說【沒有開126的SMTP代理設置】,我在網上找了很多stmp設置的文章,說的都是下圖的內容。

六、BeanShell斷言的全部代碼
名稱:BSH斷言--10000次錯誤則發送報警郵件 |
備注:根據請求失敗次數,按照一定比例配置(如:失敗10000次發一封郵件),觸發郵件發送條件 |
log.error(vars.get("Reqstatus")); int count = Integer.parseInt(vars.get("errcount").trim()); if(!(SampleResult.getResponseCode().equals("200") && SampleResult.getResponseDataAsString().equals("SUCCESS"))){ //獲取響應中的響應參數 String code = SampleResult.getResponseCode(); String msg = SampleResult.getResponseMessage(); String data = SampleResult.getResponseDataAsString(); //調試時的打印信息,正式測試時應該注釋掉下面4行log.error(); // log.error("-----------Request FALSE-----------Returncode or ResponseData is ERROR"); log.error("-----------Returncode is :\"" + code + "\""); log.error("-----------ResponseMessage is :\"" + msg + "\""); log.error("-----------ResponseData is :\"" + data + "\""); //將響應的參數賦值給對應的全局變量,用於后續郵件中使用 vars.put("respcode",code); vars.put("respmsg",msg); vars.put("respdata",data); vars.put("Reqstatus","requestNook"); count =count + 1; vars.put("errcount",count.toString()); log.error("----False------count="+count); if((count % 10000) == 0){ //sendemail=yes則if邏輯控制器會觸發發送報警郵件 vars.put("sendemail","yes"); log.error("--------It is sendemail ? :"+vars.get("sendemail")); }else{ vars.put("sendemail","no"); } //設置當前請求采樣器Sampler為失敗狀態(查看結果樹里紅色高亮顯示) SampleResult.setSuccessful(false); }else{ log.error("-----------Returncode is :\""+ SampleResult.getResponseCode()+"\""); // log.error("-----------ResponseMessage is :\""+ SampleResult.getResponseMessage()+"\""); // log.error("-----------ResponseData is :\""+ SampleResult.getResponseDataAsString()+"\""); SampleResult.setSuccessful(true); } |
六、郵件發送執行效果:
1、收到郵件

2、Jmeter腳本在測試調試狀態下的截圖
為了測試BSH腳本以及郵箱采樣器是否正常工作 ,因此設置請求錯誤數量達到 3次 就發送報警郵件,在Jmeter的查看結果樹組件結果如下:
下圖中結果樹的綠色文字:
BeanShell Sampler里面只是打印日志的 語句,綠色表示執行成功;
SMTP Sampler表示郵件發送成功,因此是綠色;

結束語:以上就是Jmeter測試過程中遇到請求失敗次數達到一定數量時,進行報警郵件發送的完整內容。
請求幫助:本人BeanShell用的不多,寫起來很啰嗦,用了很多Jmeter全局變量,但目前也沒想到更簡便的方法,如果有誰能幫我優化一下代碼或者結構,請聯系我。