表达式系统是多步探测的高级功能,支持在变量提取和断言中使用灵活的表达式语法。您可以使用内置函数、运算符和管道操作来处理响应数据,实现复杂的业务逻辑验证。
应用场景
表达式系统主要用于以下两个场景:
1. 变量提取(推荐)
从响应中提取并处理数据后保存为变量。这是表达式最常见的用途,允许您对原始响应数据进行加工处理后再使用。
2. 断言验证
验证响应是否满足预期条件。表达式可以实现复杂的条件判断,使断言更加精确和灵活。
特殊变量
表达式中可使用的内置特殊变量:
变量 | 说明 | 适用场景 |
| HTTP 响应体(完整文本) | 变量提取、断言 |
| HTTP 状态码(数字) | 断言 |
| HTTP 响应头(对象) | 变量提取、断言 |
| 生成随机 UUID | URL、请求头、请求体 |
| 当前时间戳(秒) | URL、请求头、请求体 |
| 生成 n 位随机字符串 | URL、请求头、请求体 |
内置函数
多步探测提供了丰富的内置函数,按功能分类如下:
数据提取函数
jsonpath(json, path)
从 JSON 中提取数据。这是处理 JSON 响应最常用的方法。
API 参数示例:
{
"parser": {
"parser_type": "expression",
"value": "jsonpath(@body, '$.data.users[0].id')"
}
}
regex(text, pattern, group)
使用正则表达式提取文本。适用于非 JSON 格式的响应或特定格式的数据提取。
API 参数示例:
{
"parser": {
"parser_type": "expression",
"value": "regex(@body, 'token=([a-z0-9]+)', 1)"
}
}
字符串处理函数
函数 | 说明 | 示例 |
| 转大写 |
|
| 转小写 |
|
| 去除首尾空格 |
|
| 获取长度 |
|
| 截取子串 |
|
| 替换字符串 |
|
| 拼接字符串 |
|
| 检查包含 |
|
加密/编码函数
函数 | 说明 | 示例 |
| MD5 哈希 |
|
| SHA1 哈希 |
|
| SHA256 哈希 |
|
| Base64 编码 |
|
| Base64 解码 |
|
| URL 编码 |
|
| URL 解码 |
|
工具函数
函数 | 说明 | 示例 |
| 提供默认值 |
|
| 返回第一个非空值 |
|
运算符
算术运算符
+- 加法或字符串拼接-- 减法*- 乘法/- 除法%- 取模
比较运算符
==- 等于!=- 不等于>- 大于<- 小于>=- 大于等于<=- 小于等于
逻辑运算符
&&- 逻辑与||- 逻辑或!- 逻辑非??- 空值合并
特殊运算符
三元运算符 ? :
用于条件判断和值选择:
{
"value": "@body.status == 'active' ? 'online' : 'offline'"
}管道运算符 |
将值传递给函数链式处理,使表达式更易读:
{
"value": "@body.email | trim | lower"
}使用示例
示例 1:提取并处理用户邮箱
{
"extracted_variables": [
{
"name": "user_email",
"parser": {
"parser_type": "expression",
"value": "@body.email | trim | lower"
},
"extracted_type": "http_body"
}
]
}示例 2:提取数组第一个元素
{
"extracted_variables": [
{
"name": "first_post_id",
"parser": {
"parser_type": "expression",
"value": "jsonpath(@body, '$[0].id')"
},
"extracted_type": "http_body"
}
]
}示例 3:条件提取
{
"extracted_variables": [
{
"name": "user_level",
"parser": {
"parser_type": "expression",
"value": "@body.score > 100 ? 'VIP' : 'Normal'"
},
"extracted_type": "http_body"
}
]
}示例 4:组合多个字段
{
"extracted_variables": [
{
"name": "full_name",
"parser": {
"parser_type": "expression",
"value": "concat(@body.firstName, ' ', @body.lastName) | trim"
},
"extracted_type": "http_body"
}
]
}示例 5:生成签名
{
"extracted_variables": [
{
"name": "signature",
"parser": {
"parser_type": "expression",
"value": "md5(concat(app_key, @timestamp, app_secret))"
},
"extracted_type": "http_body"
}
]
}断言中使用表达式
基础断言
{
"assertions": [
{
"type": "expression",
"target": "@status == 200"
}
]
}复杂条件断言
{
"assertions": [
{
"type": "expression",
"target": "(@status == 200 || @status == 201) && length(@body) > 0"
}
]
}JSON 字段验证
{
"assertions": [
{
"type": "expression",
"target": "@body.userId == user_id && @body.status == 'active'"
}
]
}响应内容检查
{
"assertions": [
{
"type": "expression",
"target": "contains(@body, 'success') && length(@body) > 50"
}
]
}数组长度验证
{
"assertions": [
{
"type": "expression",
"target": "length(@body) > 1"
}
]
}使用提取的变量(注意:仅限后续步骤)
{
"assertions": [
{
"type": "expression",
"target": "jsonpath(@body, '$.id') == expected_id"
}
]
}完整示例:API 测试流程
以下是一个完整的多步探测配置示例,展示如何在实际场景中使用表达式:
{
"config_variables": [
{"name": "base_url", "value": "https://jsonplaceholder.typicode.com"},
{"name": "post_id", "value": ""},
{"name": "user_id", "value": ""}
],
"steps": [
{
"step_name": "获取文章列表",
"step_type": "http",
"url": "{{base_url}}/posts",
"option": "{\"http_method\":\"GET\"}",
"extracted_variables": [
{
"name": "post_id",
"parser": {
"parser_type": "expression",
"value": "jsonpath(@body, '$[0].id')"
},
"extracted_type": "http_body"
},
{
"name": "user_id",
"parser": {
"parser_type": "expression",
"value": "jsonpath(@body, '$[0].userId')"
},
"extracted_type": "http_body"
}
],
"option": "{\"assertions\":[{\"type\":\"expression\",\"target\":\"@status == 200 && length(@body) > 0\"}]}"
},
{
"step_name": "获取文章详情",
"step_type": "http",
"url": "{{base_url}}/posts/{{post_id}}",
"option": "{\"http_method\":\"GET\",\"assertions\":[{\"type\":\"expression\",\"target\":\"@status == 200\"},{\"type\":\"expression\",\"target\":\"@body.id == post_id\"},{\"type\":\"expression\",\"target\":\"@body.userId == user_id\"}]}"
}
]
}最佳实践
1. 优先使用 JSONPath
对于 JSON 响应,jsonpath() 函数比正则表达式更可靠:
✅ "jsonpath(@body, '$.data.token')"
❌ "regex(@body, '\"token\":\"([^\"]+)\"', 1)"2. 使用管道简化代码
管道运算符使表达式更易读:
✅ "@body.email | trim | lower"
❌ "lower(trim(@body.email))"3. 提供默认值
为可能为空的值提供默认值,增强脚本的健壮性:
"@body.name | default('Anonymous')"4. 断言要具体明确
编写具体而明确的断言,确保验证的准确性:
✅ "@status == 200 && @body.code == 0 && length(@body.data) > 0"
❌ "length(@body) > 0"5. 避免过度复杂的表达式
单个表达式建议不超过 3 层嵌套。
复杂逻辑拆分为多个步骤。
常见问题
Q1:如何访问数组元素?
使用 jsonpath() 函数:
"jsonpath(@body, '$[0].id')" // 第一个元素
"jsonpath(@body, '$[*].id')" // 所有元素(返回第一个匹配)Q2:表达式断言失败如何调试?
系统会在失败时提供详细信息:
表达式内容。
实际求值结果。
相关变量的值。
Q3:能否在当前步骤的断言中使用当前步骤提取的变量?
不能。断言在变量提取之前执行。如需使用提取的变量,请在下一个步骤中进行断言。
Q4:@body.field 和 jsonpath(@body, '$.field') 有什么区别?
@body.field:简化语法,适用于简单字段访问。jsonpath(@body, '$.field'):完整语法,支持复杂路径和数组操作。
推荐: 对于数组或复杂嵌套,使用 jsonpath()。
相关参考
语法速查表
场景 | 表达式示例 |
访问简单字段 |
|
访问数组元素 |
|
字符串处理 |
|
条件判断 |
|
空值处理 |
|
加密签名 |
|
拼接字符串 |
|
状态验证 |
|
内容检查 |
|
长度验证 |
|
