JMeter利用 __MD5Hex 函数来计算内容的MD5值,然后通过断言来检查这个值是不是和预期一致。
__MD5Hex 是什么、怎么用以及怎样把它和断言结合起来检查响应数据或请求签名?
1. __MD5Hex函数是干什么的?
__MD5Hex 是 JMeter 的内置函数,用于计算一个字符串的 MD5 哈希值,并返回 32 位十六进制小写字符串。
语法:
text
${__MD5Hex(要计算的字符串, 存储结果的变量名)}
第一个参数:待计算的字符串(可以是普通文本、JMeter 变量、函数嵌套)
第二个参数:可选,指定一个变量名,将结果存进去,方便后面引用
示例:
text
${__MD5Hex(Hello World,)}
// 返回:b10a8db164e0754105b7a99be72e3fe5
如果加上变量名:
text
${__MD5Hex(${responseBody}, responseMD5)}
这样 responseMD5 变量里就保存了响应体的 MD5 值。
2. 怎样用 MD5 做断言?
主要有两种实用方法:
方法一:JSR223断言
在需要检查的请求下面添加一个 JSR223 断言(语言选 groovy),在里面直接计算并比较。这样不需要绕弯子用后置处理器和变量。
场景:证实整个响应体内容的 MD5 是不是等于预期值。
groovy
import java.security.MessageDigest
// 1. 获取响应数据(字符串)
String responseData = prev.getResponseDataAsString()
// 2. 计算 MD5
MessageDigest md = MessageDigest.getInstance("MD5")
byte[] digest = md.digest(responseData.getBytes("UTF-8")) // 注意编码
StringBuilder sb = new StringBuilder()
for (byte b : digest) {
sb.append(String.format("%02x", b))
}
String actualMD5 = sb.toString()
// 3. 预期的 MD5 值(可以从变量或直接写死)
String expectedMD5 = "b10a8db164e0754105b7a99be72e3fe5"
// 4. 比较,如果失败则设置断言失败信息
if (!actualMD5.equalsIgnoreCase(expectedMD5)) {
AssertionResult.setFailure(true)
AssertionResult.setFailureMessage(
"MD5 不一致! 预期: " + expectedMD5 + ", 实际: " + actualMD5
)
}
优点:思路完全可控,可以在断言失败信息里清楚打印出预期和实际值,排查方便。
注意:编码要和生成预期 MD5 时的一致,否则会不一致。一般用 UTF-8。
方法二:函数 + 响应断言(可视化操作)
如果不想写脚本,可以用 __MD5Hex 函数配合 响应断言,但需要先把整个响应体放进一个变量。
步骤:
提取响应体
在请求上右键 - 添加 后置处理器 -正则表达式提取器。
引用名称:fullBody
正则表达式:(?s)(.*)
模板:$1$
这样就把完整响应(含换行)存入了变量 ${fullBody}。
计算 MD5 并保存
再添加一个 后置处理器 - BeanShell 后置处理程序 或 JSR223 后置处理程序(语言选择groovy更高效)。
在脚本中写入:
groovy
// 把响应体变量的 MD5 值存入新变量 responseMD5
vars.put("responseMD5", org.apache.commons.codec.digest.DigestUtils.md5Hex(vars.get("fullBody")))
BeanShell 也可以用 JMeter 函数,但放在后置处理器脚本里更清晰
添加响应断言
在该请求下添加 断言 - 响应断言。
测试字段:选择 响应文本 或 Jmeter 变量,如果用变量方式,勾选JMeter 变量,变量名填 responseMD5。
方式一致规则:Equals 或 Substring(如果只是包含)。
要测试的方式:填入你预期的完整 32 位 MD5 字符串。
当实际 MD5 和预期不符时,断言就会报错。
3. 常见使用场景
场景一:检查文件下载内容是不是完整
下载一个文件后,服务器一般会返回文件的 MD5 值(可能在响应头或 JSON 中),用 __MD5Hex 计算响应体字节的 MD5,再和服务器给的对比。
场景二:接口签名测试
某些接口要求请求参数按规则拼接后计算 MD5 作为签名。你可以:
用 __MD5Hex 在请求中动态生成签名参数
同时用同样的思路在断言中重新计算一遍,如果服务器返回签名错误信息,说明签名思路可能正确(但这一般用来测试签名算法本身)
更常见的是,把服务器返回的数据重新用相同规则计算签名,断言和请求时上传的签名一致,证实数据未被篡改。
4. 注意事项
字符编码
MD5 是对字节序列计算的,所以中文字符、特殊符号的编码(UTF-8/GBK)会影响结果。保证生成预期值时的编码和测试时一致。
换行和空格
响应体末尾的换行 \n 或 \r\n 会被包含在字符串中,导致 MD5 不同。如果预期值是没有换行的,可以先 trim(),或者用正则提取时把换行处理掉。
__MD5Hex 和大小写
这个函数返回的是小写十六进制字符串。如果对比的预期值是大写,记得转一下。
性能
JSR223 断言使用 Groovy 时,建议勾选“缓存编译脚本”以提升执行效率。
MD5Hex 断言不是独立元件,而是 __MD5Hex 函数 + 断言组件的组合用法。最灵活稳定的实现是使用 JSR223 断言直接计算并比较,既能准确检查,又能输出清晰的失败信息。