结构图
1.准备
提前安装好JMeter Plugins Manager,后续用的到部分组件需要通过插件管理器安装,比如JSR断言、WebSocket Open Connection等组件
2.实现思路
2.1 通过HTTP请求获取token
token有过期时间,每次手动设置较为麻烦,故通过组件每次运行获取新的token
2.2 设置循环控制、断言变量
也有每次循环重置变量的作用,避免变量结果复用
2.3 建立WebSocket连接
WebSocket连接实在HTTP请求的基础上建立的,也就是在HTTP请求中高速对方,我要和你建立websocket连接,所以必要的HTTP请求头参数要带上
2.4 设置While循环控制读取CSV文件数据
2.4.1 csv文件设置,一般这样设置参数即可
变量名称:message,expected_steps
对应vars中的变量,变量值是根据分隔带JMeter自动处理的,变量名称 数量和分隔后的变量值 数量不对应也没影响,两者缺少的值会忽略或者设置为空值
2.5 设置websocket请求体数据
2.6 设置循环来保证接收到需要的响应(排除ping响应的影响)
JSR223后置处理脚本(从正确响应中拆解出需要的数据):
脚本是类似C语言的执行模式,方法在前,调用在后
import org.json.JSONObject;
import org.json.JSONArray;
// 解析read的响应数据为json格式
public JSONObject parseResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
return jsonResponse;
} catch (Exception e) {
log.info("解析read结果失败: " + e.getMessage());
return null;
}
}
// 判断action是否为chat
public Boolean processAction(JSONObject jsonResponse) {
try{
if (jsonResponse.has("action") && jsonResponse.get("action").toString().equals("chat")) {
return true;
}
else {
return false;
}
}catch (Exception e) {
System.err.println("processAction发生异常: " + e.getMessage());
return false;
}
}
// 获取read结果的steps
public List<String> getStepsList(JSONObject jsonResponse){
// 解析实际步骤
List<String> actualSteps = new ArrayList<>();
try{
JSONArray plan = jsonResponse.getJSONObject("xxxx")
.getJSONObject("data");
for (int i=0; i<plan.length(); i++) {
JSONArray steps = plan.getJSONObject(i).getJSONArray("steps");
for (int j=0; j<steps.length(); j++) {
actualSteps.add(steps.getJSONObject(j).getString("xxxx"));
}
}
}catch (Exception e) {
log.info("获取steps失败: " + e.getMessage());
}
return actualSteps;
}
// 获取csv文件中的预期步骤
public List<String> getExpectedStepsList(){
return Arrays.asList(vars.get("expected_steps").split(";"));
}
// 比较预期步骤和实际步骤是否符合
public Boolean getComparisonResult(List<String> actualSteps,List<String> expectedSteps){
//比较方法
return actualSteps.equals(expectedSteps);
}
// 获取原始响应
String response = prev.getResponseDataAsString();
// read的响应数据转为json格式
JSONObject jsonResponse = parseResponse(response);
// 仅处理action:chat的响应
if (processAction(jsonResponse)) {
// 解析实际步骤
List<String> actualSteps = getStepsList(jsonResponse);
// 获取预期步骤
List<String> expectedSteps = getExpectedStepsList();
// 对比数据
Boolean temp = getComparisonResult(actualSteps,expectedSteps);
// 实际与预期不符
if(!temp){
// 存储实际、预期数据
vars.putObject("actualSteps", actualSteps);
vars.putObject("expectedSteps", expectedSteps);
// 标记需要断言
vars.put("isAsser","true");
}
vars.put("isValidResponse", "true"); // 标记有效响应(停止读取流数据,进入下个案例循环)
}
JSR223断言(从正确响应中拆解出需要的数据):
// 断言
if ("true".equals(vars.get("isAsser"))) {
// 获取测试数据
List<String> expectedSteps = vars.getObject("expectedSteps");
List<String> actualSteps = vars.getObject("actualSteps");
String msg = vars.get("message");
String actualStepsString = actualSteps.toString();
String expectedStepsString = expectedSteps.toString();
AssertionResult.setFailure(true); // 标记断言失败
AssertionResult.setFailureMessage("案例 " + msg + " 预期不符\n" + "\t实际步骤:"
+ actualStepsString + "\n" + "\t预期步骤:" + expectedStepsString);
// 添加调试信息
log.info("当前案例: {},与预期不符合", vars.get("message"));
log.info("实际步骤列表: {}", actualSteps.toString());
log.info("预期步骤列表: {}", expectedSteps.toString());
}