浅谈后置处理器之JSON提取器
JMeter 的 JSON 提取器(JSON Extractor)是一个强大的后置处理器,它允许用户从HTTP响应、数据库查询或其他类型的响应中提取JSON数据,并将这些数据存储为变量,以便在后续的请求中重用。这对于需要动态处理基于JSON格式API测试的场景尤为有用。以下是对JSON提取器的详细说明和使用教程。
使用场景
● 参数化请求:从一个API响应中提取token或其他标识符,用于后续请求的认证或数据关联。
● 数据驱动测试:提取JSON数组中的多个值,用于遍历测试不同的数据集。
● 验证响应内容:检查特定的JSON字段是否存在或其值是否符合预期。
配置步骤
添加JSON提取器
- 在你的JMeter测试计划中,选择一个采样器(如HTTP请求)。
- 右键点击该采样器,选择“添加” > “后置处理器” > “JSON 提取器”。
配置参数
JSON 提取器提供了多个配置选项,以下是关键参数的解释:
● 名称: 给这个后置处理器一个描述性的名称,便于识别。
● Names of created variables:变量名称
● JSON Path expressions: 输入JSON路径表达式,用于定位你想要提取的数据。例如$.username会提取根对象下的username字段。
● Match No. (0 for Random):
○ 0: 随机选择一个匹配项。
○ n: 提取第n个匹配项(n为正整数)。
○ -1: 提取所有匹配项,并以变量数组形式存储。
● Compute concatenation var(suffix_ALL):匹配到的所有数值并保存,默认为空即可
● Default Values: 如果没有找到匹配的JSON路径,可以设置一个默认值。
变量命名与引用
● 变量名: 为提取的数据指定一个变量名。如果Match No.设置为-1,则应使用数组形式的变量名,如users_,这样每个匹配项将会被命名为users_1、users_2等。
示例
假设你有一个API响应如下:
{"status": "success","data": {"userId": 12345,"username": "exampleUser"}
}
要提取username值,你可以配置JSON Extractor如下:
● JSON Path expressions: $.data.username
● Names of created variables: userNameVar
● Match No.: 1
之后,在JMeter中任何地方可以通过${userNameVar}引用提取到的用户名。
应用实例
首先我们使用SpingBoot编写部分测试接口代码
@PostMapping(value = "/login",produces = "application/json;charset=UTF-8")public String authenticate(@RequestBody JSONObject request) {String validUsername = "admin";String validPassword = "password";String response = "{\"total\":2,\"data\":[{\"id\":123,\"name\":\"John Doe\",\"email\":\"johndoe@example.com\",\"phone\":\"123-456-7890\",\"address\":{\"street\":\"123 Main St\",\"city\":\"New York\",\"state\":\"NY\",\"zip\":\"10001\"},\"interests\":[\"sports\",\"music\",\"travel\"]},{\"id\":456,\"name\":\"Jane Smith\",\"email\":\"janesmith@example.com\",\"phone\":\"987-654-3210\",\"address\":{\"street\":\"456 Elm St\",\"city\":\"Los Angeles\",\"state\":\"CA\",\"zip\":\"90001\"},\"interests\":[\"reading\",\"cooking\",\"hiking\"]}]}";if (request.getString("username").equals(validUsername) && request.getString("password").equals(validPassword)) {return response;} else {return response;}}
我们编写如下测试脚本
线现程组:保持默认
HTTP信息头管理器:名称content-type,值为application/json;charset=UTF-8
HTTP请求:协议http,服务器名称或IP为127.0.0.1,端口设置为8091,方法为post,路径/login,内容编码为utf-8,消息体数据设置如下
{"username": "admin","password": "password"}
运行脚本,查看结果树,在HTTP请求的响应数据中Response Body查看结果如下(已经美化JSON格式):
{"total": 2,"data": [{"address": {"zip": "10001","city": "New York","street": "123 Main St","state": "NY"},"phone": "123-456-7890","name": "John Doe","id": 123,"interests": ["sports","music","travel"],"email": "johndoe@example.com"},{"address": {"zip": "90001","city": "Los Angeles","street": "456 Elm St","state": "CA"},"phone": "987-654-3210","name": "Jane Smith","id": 456,"interests": ["reading","cooking","hiking"],"email": "janesmith@example.com"}]
}
情况1:返回值中提取total数据
JSON提取器中Names of created variables设置为var,JSON Path expressions设置为total或者$.total,两种效果一致,Match No. (0 for Random)设置为-1,Default Values设置为NotFound。
运行脚本,查看结果树中响应数据的Response Body
var_1=2
var_matchNr=1
情况2:返回值中提取address数据
JSON提取器中Names of created variables设置为var,JSON Path expressions设置为data[*].address或者$.data[*].address,两种效果一致,Match No. (0 for Random)设置为-1,Default Values设置为NotFound。
运行脚本,查看结果树中响应数据的Response Body
var_1={“zip”:“10001”,“state”:“NY”,“city”:“New York”,“street”:“123 Main St”}
var_2={“zip”:“90001”,“state”:“CA”,“city”:“Los Angeles”,“street”:“456 Elm St”}
var_matchNr=2
情况3:返回值中提取address数只需要上述情况2中var_1的数据
JSON提取器中Names of created variables设置为var,JSON Path expressions设置为data[0].address或者$.data[0].address,两种效果一致,Match No. (0 for Random)设置为-1,Default Values设置为NotFound。
运行脚本,查看结果树中响应数据的Response Body
var_1={“zip”:“10001”,“state”:“NY”,“city”:“New York”,“street”:“123 Main St”}
var_matchNr=1
情况4:返回值中提取interests的数据
JSON提取器中Names of created variables设置为var,JSON Path expressions设置为data[*].interests[*]或者$.data[*].interests[*],两种效果一致,Match No. (0 for Random)设置为-1,Default Values设置为NotFound。
运行脚本,查看结果树中响应数据的Response Body
var_1=sports
var_2=music
var_3=travel
var_4=reading
var_5=cooking
var_6=hiking
var_matchNr=6
情况5:返回值中提取interests的数据第一行的数据,即Sports和Reading
JSON提取器中Names of created variables设置为var,JSON Path expressions设置为data[*].interests[0]或者$.data[*].interests[0],两种效果一致,Match No. (0 for Random)设置为-1,Default Values设置为NotFound。
运行脚本,查看结果树中响应数据的Response Body
var_1=sports
var_2=reading
var_matchNr=2
情况6:勾选Compute concatenation var(suffix_ALL)
初勾选Compute concatenation var(suffix_ALL),其他设置跟情况5一直。
运行脚本,查看结果树中响应数据的Response Body
var_1=sports
var_2=reading
var_ALL=sports,reading
var_matchNr=2
注意事项
● 确保JSON路径表达式正确无误。
● 当提取多个值时,合理设置Match No.和变量名格式,避免数据混乱。
● 对于复杂的JSON结构,深入理解JSONPath语法将大大提高提取效率。
通过以上步骤和注意事项,你应该能够有效地使用JMeter的JSON提取器来处理和利用JSON响应数据,进而构建更加动态和强大的性能测试脚本。