一文搞懂JMeter关联:从基础到进阶

前言

在接口测试中,接口之间的依赖关系是最常见的问题。A接口返回的token需要传给B接口,B接口返回的订单ID需要传给C接口…这时候就需要用到”关联”技术。

本文详细介绍JMeter中各种关联方式,让你轻松应对接口依赖场景。

什么是关联

关联(Correlation):将上一个请求的响应数据提取出来,作为下一个请求的入参。

典型场景

1
2
3
1. 登录接口 → 返回 token
2. 获取用户信息接口 → 需要携带 token
3. 下单接口 → 需要 token 和用户ID

正则表达式提取器

基础用法

假设登录接口返回:

1
2
3
4
5
6
7
{
"code": 200,
"data": {
"token": "abc123xyz",
"userId": 10001
}
}

配置正则表达式提取器:

  • 引用名称login_token
  • 正则表达式"token"\s*:\s*"([^"]+)"
  • 模板$1$
  • 匹配数字1

提取多个值

如果需要同时提取token和userId:

1
2
3
4
5
6
7
{
"data": {
"token": "abc123xyz",
"userId": 10001,
"username": "test_user"
}
}

正则表达式:

1
"token"\s*:\s*"([^"]+)".*?"userId"\s*:\s*(\d+).*?"username"\s*:\s*"([^"]+)"

引用方式:

  • ${login_token_g1} → abc123xyz
  • ${login_token_g2} → 10001
  • ${login_token_g3} → test_user

JSON提取器

基础用法

JMeter 3.0+ 支持JSON提取器,处理JSON响应更方便:

1
$.data.token

配置:

  • Names of created variableslogin_token
  • JSON Path Expressions$.data.token
  • Match No.1

提取嵌套数据

1
2
3
4
5
6
7
8
9
{
"data": {
"user": {
"profile": {
"avatar": "https://example.com/avatar.jpg"
}
}
}
}

JSON Path:

1
$.data.user.profile.avatar

提取数组数据

1
2
3
4
5
6
7
8
{
"data": {
"items": [
{"id": 1, "name": "商品A"},
{"id": 2, "name": "商品B"}
]
}
}

提取第一个商品的名称:

1
$.data.items[0].name

提取所有商品ID:

1
$.data.items[*].id

XPath提取器

适用于XML格式响应:

1
2
3
4
5
6
<response>
<user>
<id>10001</id>
<name>测试用户</name>
</user>
</response>

XPath表达式:

1
//user/id/text()

Boundary Extractor(边界提取器)

JMeter 5.0+ 新增的提取器,比正则更简单:

  • Left Boundary"token": "
  • Right Boundary",
  • 引用名称login_token

后置处理器执行顺序

当一个请求有多个后置处理器时,执行顺序为:

  1. Boundary Extractor
  2. JSON Extractor
  3. JSON JMESPath Extractor
  4. XPath Extractor
  5. XPath2 Extractor
  6. Regular Expression Extractor

调试技巧

Debug Sampler

添加Debug Sampler,查看所有变量:

  • __jmeterSampler - 查看采样器信息
  • 勾选查看变量输出

查看结果树

在”查看结果树”中添加变量显示:

  • 勾选”Save Response Data”
  • 响应中可看到 ${variable_name} 被解析后的值

实战案例:完整登录流程

Step 1: 登录获取Token

1
2
3
4
POST /api/login
Content-Type: application/json

{"username": "test", "password": "123456"}

响应:

1
2
3
4
5
6
7
{
"code": 200,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 7200
}
}

添加JSON提取器:

  • 变量名:access_token
  • JSON Path:$.data.token

Step 2: 获取用户信息

1
2
GET /api/user/info
Authorization: Bearer ${access_token}

Step 3: 获取商品列表

1
2
GET /api/products?page=1&pageSize=10
Authorization: Bearer ${access_token}

响应:

1
2
3
4
5
6
7
8
9
10
{
"code": 200,
"data": {
"list": [
{"id": 1001, "name": "商品A", "price": 99},
{"id": 1002, "name": "商品B", "price": 199}
],
"total": 100
}
}

提取第一个商品ID:

  • JSON Path:$.data.list[0].id
  • 变量名:first_product_id

Step 4: 加入购物车

1
2
3
4
5
POST /api/cart/add
Authorization: Bearer ${access_token}
Content-Type: application/json

{"productId": ${first_product_id}, "quantity": 1}

常见问题

Q1: 提取值为空?

  1. 检查JSON Path或正则表达式是否正确
  2. 使用Debug Sampler确认响应内容
  3. 检查变量引用名称是否一致

Q2: 变量未传递?

  1. 确认变量作用域(仅在当前线程组有效)
  2. 检查变量引用格式 ${variable_name}
  3. 确认执行顺序(提取器在请求之前执行)

Q3: 特殊字符转义?

使用__urlencode__unescape函数处理。

总结

提取器 适用场景 难度
正则表达式提取器 通用场景 ⭐⭐⭐
JSON提取器 JSON响应 ⭐⭐
XPath提取器 XML响应 ⭐⭐⭐
边界提取器 简单场景

建议:

  • JSON响应优先使用JSON提取器
  • 复杂匹配使用正则表达式提取器
  • XML响应使用XPath提取器
  • 简单边界使用边界提取器

掌握关联技术,你就能轻松处理各种接口依赖场景了!