JMeter 兼容整数 / 小数金额断言方案:JSONPath 转为 JSR223 Groovy 断言实战

一、业务场景痛点

在接口压测、自动化接口校验中,同个金额字段JE因后端数据库不同,返回格式不一致:

  • 达梦数据库:"JE":6208(整数)
  • Oracle 数据库:"JE":6208.0 / "JE":6208.00(1 位 / 2 位小数)

使用JMeter 原生 JSON 断言会出现匹配失败:

  1. 预期值填6208,实际6208.00 → 字符串不一致,断言失败;
  2. 预期值填6208.0,实际6208 → 同样匹配报错;
  3. 开启正则匹配^6208(\.0+)?$,JSON 断言对 Number 类型 JSON 值存在原生匹配 BUG,依然偶现失败。

同时业务需要根据单据编号变量DJBH1动态筛选指定行数据 ,原 JSONPath 表达式:$.data[?(@.DJBH=="${DJBH1}")].JE,原生断言无法做数值运算适配,因此改用JSR223 Groovy 断言实现统一兼容校验。

二、原 JSONPath 逻辑说明

$.data[?(@.DJBH=="${DJBH1}")].JE

  1. $.data:定位 JSON 顶层 data 数组;
  2. [?(@.DJBH=="${DJBH1}")]:过滤数组中DJBH字段等于 JMeter 变量${DJBH1}的单行数据;
  3. .JE:提取该行金额字段,是我们需要断言的目标值。

三、JSR223 Groovy 断言实现方案

3.1 操作步骤

  1. 目标 HTTP 取样器右键 → 添加 → 断言 → JSR223 Assertion
  2. 脚本语言选择:groovy
  3. 清空默认内容,粘贴下述代码。

3.2 完整通用脚本

groovy

复制代码
import groovy.json.JsonSlurper
//1.解析接口返回JSON报文
def json = new JsonSlurper().parseText(prev.getResponseDataAsString())
//2.获取JMeter中预存的单据编号变量DJBH1
def targetDJBH = vars.get("DJBH1")
//3.筛选DJBH等于变量的行,等价原JSONPath过滤逻辑
def targetRow = json.data.find{it.DJBH == targetDJBH}
//4.取值并统一转为Double,自动兼容整数、1位小数、2位小数
def realJE = targetRow?.JE as Double
//5.配置预期金额,按需修改
def expectJE = 6208

//6.断言逻辑:找不到数据 或 金额差值超0.01则失败
if(realJE == null || Math.abs(realJE - expectJE) > 0.01){
    AssertionResult.setFailure(true)
    AssertionResult.setFailureMessage("单据${targetDJBH}金额校验失败:实际值=${realJE},预期值=${expectJE}")
}

3.3 核心原理

  1. 类型统一as Double6208、6208.0、6208.00全部转为浮点数字,从数值层面对比,彻底规避字符串格式差异;
  2. 容错处理targetRow?.JE安全导航写法,筛选不到单据时不会空指针异常;
  3. 容差设计Math.abs(差值)>0.01,规避 Java 浮点运算精度 BUG(如 6208.0000000001);
  4. 变量联动vars.get("DJBH1")读取 JMeter 上下文变量,和原 JSONPath 变量用法完全一致。

四、脚本灵活修改说明

  1. 修改目标变量 :若单据变量从DJBH1改为DJBH,仅修改vars.get("DJBH1")vars.get("DJBH")
  2. 修改预期金额 :仅改动def expectJE = 6208后的数字;
  3. 修改 JSON 层级 :若 JE 不在data下,调整json.data.find为对应层级,和 JSONPath 改层级逻辑一致。

五、方案优势总结

  1. 全格式兼容:整数 / 1 位小数 / 2 位小数三种数据库返回格式全部通过;
  2. 稳定性更强:脱离 JMeter 原生 JSON 断言字符串匹配缺陷,不受 JSON 字段数据类型(Number)限制;
  3. 可读性高:失败提示输出单据号、实际值、预期值,排查问题效率远高于原生断言;
  4. 拓展方便:后续如需多字段联合断言、动态传参预期值,可直接在 Groovy 脚本扩展。

六、拓展:极简精简版脚本(快速部署)

如需快速使用,可选用精简代码,功能完全一致:

groovy

复制代码
def json = new groovy.json.JsonSlurper().parseText(prev.responseDataAsString())
def djbh = vars.get("DJBH1")
def je = json.data.find{it.DJBH==djbh}?.JE as Double
def exp = 6208
if(Math.abs((je?:0)-exp)>0.01) AssertionResult.setFailure(true,"单据${djbh}金额异常:实际${je}预期${exp}")
相关推荐
1candobetter1 天前
JMeter 常见功能在调试阶段与正式压测阶段的使用建议
jmeter·压力测试
Demon1_Coder1 天前
微服务-jmeter
jmeter
BullSmall2 天前
JMeter AI 插件
人工智能·jmeter
BullSmall2 天前
JMeter插件变灰?3步解决FeatherWand问题
jmeter
海的透彻3 天前
jmeter预制处理器JSR223-加解密
开发语言·jmeter·sm2·jsr233
oh-pinpin3 天前
【jmeter】-脚本-文件上传接口实现
jmeter
星轨zb6 天前
JUC 到 Redis 分布式锁:一次关于高并发的性能压测实验
java·redis·分布式·jmeter
泥水沟的胖头鱼8 天前
关于jmeter修改 JVM 堆,到底是在jmeter.properties还是jmeter.bat?
jvm·jmeter·压力测试