BeanShell簡介
BeanShell是使用Java語法的一套腳本語言,在JMeter的多種組件中都有BeanShell的身影,如:
- 定時器:BeanShell Timer
- 前置處理器:BeanShell PreProcessor
- 采樣器:BeanShell Sampler
- 后置處理器:BeanShell PostProcessor
- 斷言:BeanShell Assert
- 監聽器:BeanShell Listener
通過BeanShell可以對請求數據、響應數據或環境變量進行更加靈活的處理和判斷。
Beanshell有一些默認的內置變量和方法,用戶可以通過這些變量與JMeter進行交互,比如:
- prInt:非GUI模式下打印信息(輸出信息到stdout)
- log:輸出信息到日志(文件)
- log.debu("調試信息")
- log.info("響應狀態碼" + ResponseCode)
- log.warn("警告信息")
- log.error("出錯信息")
- ResponseCode:響應狀態碼(String類型)
- ResponseHeaders:響應頭(String類型)
- prev:獲取當前請求結果
- prew.getResponseDataAsString():獲取響應體數據(String類型)
- prew.getResponseCode():獲取狀態碼(同ResponseCode,String類型)
- vars: 操作jmeter變量
- String var1 = vars.get("變量名"):獲取變量的值(假設為String類型)
- vars.put("變量名", 變量值):設置變量值
- props: 操作JMeter屬性
- props.get(String,String) 可以獲取Jmeter中已經生成的屬性
- props.put(String,String) 可以創建和更新Jmeter屬性
- ctx:獲取當前線程上下文數據(可獲取所有信息)
- ctx.getVariables("變量名"):獲取變量值(同vars.get())
- ctx.setVariables("變量名", "變量值"):設置變量(同vars.put())
- ctx.getProperties("屬性名"):獲取屬性值(同props.get())
- ctx.setProperties("屬性名","屬性值"):設置屬性(同props.put())
- ctx.getPreviousResult():獲取當前請求結果同(prev)
- ctx.getCurrentSampler():獲取當前采樣器
- ctx.getPreviousSampler():獲取前一采樣器
- ctx.getThreadNum():獲取線程數
- ctx.getThreadGroup():獲取線程組
- ctx. getThread():獲取當前線程
- ctx.getEngine():獲取引擎
- ctx.isSamplingStarted():判斷采樣器是否啟動
- ctx.isRecording():判斷是否開啟錄制
- ctx.getSamplerContext():獲取采樣器山下文數據
ctx詳細API可參考:JMeter上下文
BeanShell斷言
BeanShell斷言中可以通過ResponseCode、ResponseHeaders及pre.getResponseDataAsString()來分別獲得String格式的響應狀態碼、響應頭、響應體數據,結合if判斷通過變量Failure=false或Failure=true來設置斷言是否通過,當設置Failure=true時,還可以設置FailureMessage來設置失敗原因。
狀態碼斷言
//狀態碼斷言
log.info("狀態碼:" + ResponseCode);
if(ResponseCode.equals("200")){
Failure=false;
}
else{
Failure=true;
FailureMessage="響應狀態碼非200"; //指定失敗原因
}
注:字符串只能使用雙引號,字符串相等要使用"".equals("")
響應體包含特定字符
//獲取響應數據
String response = prev.getResponseDataAsString();
log.info("響應體:" + response);
//響應數據包含
if(response.contains("登錄成功")){
Failure=false;
}
else{
Failure=true;
FailureMessage="響應數據不包含登錄成功";
}
JSON響應體字段提取及斷言
將String類型的響應體轉為JSON對象並操作需要額外的jar包,可以使用org.json或gson,下載地址如下:
以json.jar為例,下載后將其放入JMeter/lib目錄下,重啟JMeter,添加BeanShell斷言,如下:
//JSON響應斷言
import org.json.*; //導入org.json包
String response = prev.getResponseDataAsString(); //獲取響應數據
JSONObject responseJson = new JSONObject(response); //轉為JSON對象
String message = responseJson.getString("message");
log.info("響應message字段:" + message);
if(message.equals("成功")){
Failure=false;
}
else{
Failure=true;
FailureMessage="響應message字段非成功";
}
JSONObject對象除了getString()方法外,還支持
- getBoolean("字段名") :獲取布爾類型字段值
- getInt("字段名"):獲取整型字段值
- getLong("字段名"):獲取長整型字段值
- getDouble("字段名"):獲取雙精型字段值
- getJSONObject("字段名"):獲取嵌套Object類型字段值,JSONObject類型
- getJSONArray("字段名"):獲取嵌套Array類型,JSONArray類型
響應頭解析
響應頭原本為String類型,可以通過分割遍歷組裝成Map類型來提取響應頭中的項
import java.util.HashMap;
import java.util.Map;
//將字符串用換行符 截取為adc數組
String [] headersList = ResponseHeaders.split("\n");
Map headersMap = new HashMap(); //創建HashMap來從新組裝headers
for(int i=1;i<headersList.length;i++){
String [] itemList=headersList[i].split(": "); // 將每一條Headerr項按冒號分割
headersMap.put((itemList[0]), itemList[1]); // 分鍵值放入HashMap
}
String contentType = headersMap.get("Content-Type"); // 提取相應項
log.info("響應Content-Type:" + contentType)