多步探测表达式使用指南

更新时间:
复制为 MD 格式

表达式系统是多步探测的高级功能,支持在变量提取和断言中使用灵活的表达式语法。您可以使用内置函数、运算符和管道操作来处理响应数据,实现复杂的业务逻辑验证。

应用场景

表达式系统主要用于以下两个场景:

1. 变量提取(推荐)

从响应中提取并处理数据后保存为变量。这是表达式最常见的用途,允许您对原始响应数据进行加工处理后再使用。image.png

2. 断言验证

验证响应是否满足预期条件。表达式可以实现复杂的条件判断,使断言更加精确和灵活。image.png

特殊变量

表达式中可使用的内置特殊变量:

变量

说明

适用场景

@body

HTTP 响应体(完整文本)

变量提取、断言

@status

HTTP 状态码(数字)

断言

@headers

HTTP 响应头(对象)

变量提取、断言

@uuid

生成随机 UUID

URL、请求头、请求体

@timestamp

当前时间戳(秒)

URL、请求头、请求体

@random(n)

生成 n 位随机字符串

URL、请求头、请求体

内置函数

多步探测提供了丰富的内置函数,按功能分类如下:

数据提取函数

jsonpath(json, path)

从 JSON 中提取数据。这是处理 JSON 响应最常用的方法。image.png

API 参数示例:

{
  "parser": {
    "parser_type": "expression",
    "value": "jsonpath(@body, '$.data.users[0].id')"
  }
}

regex(text, pattern, group)

使用正则表达式提取文本。适用于非 JSON 格式的响应或特定格式的数据提取。image.png

API 参数示例:

{
  "parser": {
    "parser_type": "expression",
    "value": "regex(@body, 'token=([a-z0-9]+)', 1)"
  }
}

字符串处理函数

函数

说明

示例

upper(str)

转大写

upper(@body.name)"JOHN"

lower(str)

转小写

lower(@body.email)"test@example.com"

trim(str)

去除首尾空格

trim(@body.token)

length(str)

获取长度

length(@body) > 100

substring(str, start, end)

截取子串

substring(@body.id, 0, 8)

replace(str, old, new)

替换字符串

replace(@body.url, 'http', 'https')

concat(str1, str2, ...)

拼接字符串

concat('User-', @body.id)

contains(str, substr)

检查包含

contains(@body, 'success')

加密/编码函数

函数

说明

示例

md5(str)

MD5 哈希

md5(@body.email)

sha1(str)

SHA1 哈希

sha1(password)

sha256(str)

SHA256 哈希

sha256(app_key + @timestamp)

base64(str)

Base64 编码

base64('username:password')

base64_decode(str)

Base64 解码

base64_decode(@body.encoded)

urlencode(str)

URL 编码

urlencode(@body.query)

urldecode(str)

URL 解码

urldecode(@body.param)

工具函数

函数

说明

示例

default(val, defaultVal)

提供默认值

default(@body.name, 'unknown')

coalesce(val1, val2, ...)

返回第一个非空值

coalesce(@body.token, backup_token, 'guest')

运算符

算术运算符

  • + - 加法或字符串拼接

  • - - 减法

  • * - 乘法

  • / - 除法

  • % - 取模

比较运算符

  • == - 等于

  • != - 不等于

  • > - 大于

  • < - 小于

  • >= - 大于等于

  • <= - 小于等于

逻辑运算符

  • && - 逻辑与

  • || - 逻辑或

  • ! - 逻辑非

  • ?? - 空值合并

特殊运算符

三元运算符 ? :

用于条件判断和值选择:

{
  "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"
    }
  ]
}

断言中使用表达式

基础断言image.png

{
  "assertions": [
    {
      "type": "expression",
      "target": "@status == 200"
    }
  ]
}

复杂条件断言image.png

{
  "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 测试流程

以下是一个完整的多步探测配置示例,展示如何在实际场景中使用表达式:image.png

{
  "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.fieldjsonpath(@body, '$.field') 有什么区别?

  • @body.field:简化语法,适用于简单字段访问。

  • jsonpath(@body, '$.field'):完整语法,支持复杂路径和数组操作。

推荐: 对于数组或复杂嵌套,使用 jsonpath()

相关参考

语法速查表

场景

表达式示例

访问简单字段

@body.userId

访问数组元素

jsonpath(@body, '$[0].id')

字符串处理

@body.email | trim | lower

条件判断

@body.age > 18 ? 'adult' : 'minor'

空值处理

@body.name ?? 'default'

加密签名

md5(app_key + @timestamp)

拼接字符串

concat('prefix-', @body.id, '-suffix')

状态验证

@status == 200 && @body.success == true

内容检查

contains(@body, 'success')

长度验证

length(@body) > 100