JMeter对多层级JSON的断言实战指南
在接口自动化测试中,JSON是最常见的数据交换格式之一,而实际业务场景下的JSON响应往往包含多层嵌套结构(如用户信息中嵌套地址列表,订单详情中嵌套商品信息等),如何对多层级JSON进行精准断言,确保接口返回的数据符合预期,是JMeter测试中的核心环节,本文将详细介绍JMeter中针对多层级JSON的断言方法,从基础到进阶,助你不同场景下的断言技巧。
JSON断言的核心思路
多层级JSON断言的本质是通过特定路径定位目标字段,并对其值、类型、存在性等条件进行校验,无论是单层还是多层JSON,断言的核心逻辑一致,关键在于如何准确描述嵌套字段的路径,JMeter提供了多种断言组件,其中JSON断言(JSON Assertion)和JSON Extractor(JSON提取器)+ 正则断言/Beanshell断言是最常用的两种方案,前者适合直接校验JSON结构,后者适合灵活处理复杂逻辑。
准备工作:构造多层级JSON响应示例
为了演示断言方法,我们先构造一个典型的多层级JSON响应示例(假设为用户订单接口的返回数据):
{
"code": 0,
"message": "success",
"data": {
"userId": "10086",
"userName": "张三",
"userLevel": "VIP",
"orders": [
{
"orderId": "ORDER001",
"orderTime": "2023-10-01 10:00:00",
"products": [
{
"productId": "P001",
"productName": "iPhone 15",
"price": 5999,
"quantity": 1
},
{
"productId": "P002",
"productName": "AirPods Pro",
"price": 1999,
"quantity": 2
}
],
"totalAmount": 9977
},
{
"orderId": "ORDER002",
"orderTime": "2023-10-02 14:30:00",
"products": [
{
"productId": "P003",
"productName": "MacBook Pro",
"price": 14999,
"quantity": 1
}
],
"totalAmount": 14999
}
],
"address": {
"province": "北京市",
"city": "朝阳区",
"detail": "三里屯街道1号"
}
}
}
方法一:使用JSON断言(JSON Assertion)—— 直观校验JSON结构
JSON断言是JMeter内置的专门用于JSON格式校验的组件,支持检查字段是否存在、字段值是否匹配、字段类型是否正确等,适合直接对JSON整体结构进行断言。
添加JSON断言
在HTTP请求的“后置处理器”或“断言”中添加JSON Assertion组件(路径:右键HTTP请求 → 添加 → 断言 → JSON Assertion)。
关键参数配置
JSON断言的核心参数如下:
| 参数 | 说明 |
|---|---|
| JSON Path expressions | JSON路径表达式,用于定位目标字段(支持多层嵌套,用或[]表示层级) |
| Expected Value | 期望值(可填写具体值,或留空仅检查字段存在性) |
| JSON Schema | 是否校验JSON Schema(高级用法,需定义Schema文件) |
| Compute for | 校验范围(主JSON、子JSON、所有匹配项) |
| Invert Assertion | 是否反转断言结果(如“字段不存在”时返回成功) |
多层级JSON断言实战
(1)校验顶层字段存在性
- 需求:检查返回JSON中是否存在
code、message、data字段。 - 配置:
- JSON Path expressions:(表示根节点,也可直接写
code、message、data) - Expected Value:留空(仅检查字段存在)
- Compute for:选择
Main sample and sub-samples(校验主JSON)
- JSON Path expressions:(表示根节点,也可直接写
- 结果:若
code、message、data均存在,断言通过;否则失败。
(2)校验嵌套字段值
- 需求:检查用户ID为
10086,用户名为张三,省份为北京市。 - 配置:
- JSON Path expressions:
$.data.userId(表示根,.data进入data对象,.userId取userId字段)$.data.userName$.data.address.province
- Expected Value:分别填写
10086、张三、北京市
- JSON Path expressions:
- 结果:所有路径对应的值与期望值一致时断言通过。
(3)校验数组内元素
- 需求:检查订单列表
orders中是否存在orderId为ORDER001的订单,且该订单的totalAmount为9977。 - 配置:
- JSON Path expressions:
$.data.orders[?(@.orderId == 'ORDER001')].totalAmount(使用过滤表达式筛选数组元素)
- Expected Value:
9977
- JSON Path expressions:
- 说明:JSON Path数组过滤语法
?(@.字段 == 值)可精准定位数组内特定元素,适合动态数据校验。
(4)校验字段类型
- 需求:检查
code为整数,userId为字符串,totalAmount为数字。 - 配置:
- JSON Path expressions:
$.code(Expected Value留空,但需在“Field to check”中选择JSON Type)$.data.userId$.data.orders[0].totalAmount
- Field to check:选择
JSON Type(校验字段类型而非值) - Expected Value:填写对应类型(
int、string、number)
- JSON Path expressions:
- 结果:字段类型与期望一致时通过。
方法二:使用JSON Extractor + 其他断言 —— 灵活处理复杂逻辑
JSON断言适合直接校验,但面对需要“先提取值再校验逻辑”(如校验计算结果、多字段关联关系)的场景,可结合JSON Extractor(JSON提取器)提取目标值,再用响应断言或Beanshell断言进行校验。
添加JSON Extractor
在HTTP请求的“后置处理器”中添加JSON Extractor(路径:右键HTTP请求 → 添加 → 后置处理器 → JSON Extractor),用于从JSON中提取指定路径的值。
关键参数配置
| 参数 | 说明 |
|---|---|
| Name of created variable | 提取值的变量名(后续断言中通过${变量名}引用) |
| JSON Path expressions | JSON路径表达式(同JSON断言) |
| Match No. | 匹配规则(0:随机一个,1:第一个,-1:所有,用逗号分隔) |
| Default Value | 提取失败时的默认值 |
实战:校验订单总金额计算是否正确
-
需求:校验每个订单的
totalAmount是否等于products中所有商品price * quantity的和。 -
步骤: (1)提取所有订单的
totalAmount- JSON Extractor配置:
- Name of created variable:
totalAmounts - JSON Path expressions:
$.data.orders[*].totalAmount([*]表示取所有元素的该字段) - Match No.:
-1(提取所有值,结果为逗号分隔的字符串,如9977,14999)
- Name of created variable:
(2)提取所有订单的商品列表
- 添加第二个JSON Extractor:
- Name of created variable:
orderProducts - JSON Path expressions:
$.data.orders[*].products(提取每个订单的products数组)
- Name of created variable:
(3)使用Beanshell断言校验计算逻辑
-
添加Beanshell断言(路径:右键HTTP请求 → 添加 → 断言 → Beanshell断言),编写Java代码校验:
// 提取的totalAmounts为字符串"9977,14999",需转为List<Double> String[] totalAmountArray = totalAmounts.split(","); List<Double> expectedTotalAmounts = new ArrayList<>(); for (String amount : totalAmountArray) { expectedTotalAmounts.add(Double.parseDouble(amount)); } // 遍历每个订单的商品,计算实际总金额 List<List<Map<String, Object>>> all
- JSON Extractor配置:



还没有评论,来说两句吧...