当内置的JSONPath和正则断言在复杂业务场景中捉襟见肘时,真正的测试高手会转向更强大的武器——自定义脚本断言。这就像给测试工程师配上了一把瑞士军刀,面对各种刁钻的校验需求都能游刃有余。
在真实的业务测试中,我们经常会遇到这些让人头疼的情况:
传统断言方式的局限性:
提示:当你的断言逻辑超过3个条件判断时,就该考虑使用脚本断言了
MeterSphere基于JMeter实现,提供了完整的Beanshell脚本支持。以下是最常用的内置对象:
| 对象名称 | 类型 | 典型用途 | 示例代码 |
|---|---|---|---|
prev |
SampleResult | 获取响应数据 | prev.getResponseDataAsString() |
vars |
JMeterVariables | 操作变量 | vars.put("token", "abc123") |
ctx |
JMeterContext | 上下文信息 | ctx.getPreviousResult() |
log |
Logger | 记录日志 | log.info("调试信息") |
基础脚本模板:
java复制// 获取响应内容
String response = prev.getResponseDataAsString();
// 业务校验逻辑
if(!response.contains("expected_value")) {
AssertionResult.setFailure(true);
AssertionResult.setFailureMessage("校验失败:未找到预期值");
}
让我们以一个需要短信验证码的登录接口为例,演示多维度校验:
java复制// 检查登录后跳转页面
String html = prev.getResponseDataAsString();
// 验证标题
String expectedTitle = "<title>用户中心 - 我的账户</title>";
if(!html.contains(expectedTitle)) {
AssertionResult.setFailureMessage("页面标题不符");
AssertionResult.setFailure(true);
}
// 验证登录用户显示
Pattern userPattern = Pattern.compile("<span class=\"username\">(.*?)</span>");
Matcher matcher = userPattern.matcher(html);
if(!matcher.find() || !matcher.group(1).equals(vars.get("username"))) {
AssertionResult.setFailureMessage("用户名显示异常");
AssertionResult.setFailure(true);
}
结合JDBC请求,可以验证数据一致性:
java复制// 获取JDBC查询结果
String dbCount = vars.get("user_login_count");
// 验证登录记录
if(Integer.parseInt(dbCount) <= 0) {
AssertionResult.setFailureMessage("登录记录未更新");
AssertionResult.setFailure(true);
}
java复制// 获取订单创建接口的变量
String orderId = vars.get("order_id");
// 调用查询接口验证
String queryResponse = prev.getResponseDataAsString();
if(!queryResponse.contains("\"status\":\"PAID\"")) {
AssertionResult.setFailureMessage("订单"+orderId+"支付状态异常");
AssertionResult.setFailure(true);
}
异常处理最佳实践:
java复制try {
JSONObject json = new JSONObject(prev.getResponseDataAsString());
if(json.getInt("code") != 200) {
throw new Exception("业务状态码异常");
}
} catch(Exception e) {
AssertionResult.setFailureMessage(e.getMessage());
AssertionResult.setFailure(true);
}
日志输出策略:
java复制log.info("响应数据:" + prev.getResponseDataAsString());
System.out.println("调试变量:" + vars.get("key"));
代码复用方案:
source()函数引入外部脚本性能注意事项:
在实际电商项目压力测试中,我们通过脚本断言发现了支付状态同步的边界条件问题。当并发量超过2000TPS时,有约0.3%的订单会出现"支付成功但状态未更新"的情况,这正是通过传统的响应断言无法发现的深层业务逻辑缺陷。