JMESPath提取返回结果
前言
- 本篇来学习如何使用JMESPath在 extract和 validate 的时候提取响应报文中的值
JMESPath简介
python中使用jmespath
pip install jmespath
# -*- coding: utf-8 -*-
# @Time : 2022/2/20
# @Author : 大海
import jmespath
# jmespath表达式,想要提取的值
value = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
print(value) # baz
# -*- coding: utf-8 -*-
# @Time : 2022/2/20
# @Author : 大海
import jmespath
# 有点类似正则re模块,先使用compile编译表达式
expression = jmespath.compile('foo.bar')
a = expression.search({'foo': {'bar': 'baz'}})
b = expression.search({'foo': {'bar': 'other'}})
print(a) # baz
print(b) # other
基本表达式
- 字典取值,根据key获取value
- 嵌套字典取值,一层一层取值
- list根据索引取值,索引从0开始
- dict 嵌套list取值
切片
- list可以使用切片取值,和python语法一致: 一般形式是[start:stop:step]
- 取值0-4,使用[0,5] ,不包含结束索引的值
- 省略开始索引,表示从索引 0 开始取值
- 省略始末索引表示取索引,第三个值为步长
- 反转list [::-1]
通配符*的使用
- 取出列表中所有的 first 对应的名称 people[*].first
- 取出列表中前 2 个 first 对应的名称 people[:2].first
- 取出 ops 对象的任意属性对应的numArgs ops.*.numArgs
过滤器使用
- 过滤器表达式是为数组定义的,其一般形式为 [? <表达式> <比较器> <表达式>]
- 常用的比较表达式可以使用 ==, !=, <, <=, >, > =
- 假设我们有一个机器列表,每个机器都有一个名称和一个 状态。我们想要所有正在运行的机器的名称
管道表达式
- 如果查询的结果是一个list,如果我想取出结果里面的第一个可以使用管道符 |
多选
- 可以创建JSON文档中不存在的元素
函数的使用
- 结果的数量
- 打印age最大的name
- 函数与过滤器结合使用
extract 提取变量
{
"args": {
"foo1": "bar11",
"foo2": "bar21",
"sum_v": "3"
},
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-6211933f-24cf77f24d4c33f642e58f91",
"user-agent": "PostmanRuntime/7.29.0",
"accept": "*/*",
"postman-token": "42f334a1-a634-4aad-9eb1-0a3dec8e340f",
"accept-encoding": "gzip, deflate, br",
"cookie": "sails.sid=s%3AiNXWktAi8DbacjpSqG3Kjw3WrRKUSiVd.0ie7508ENALgRVOIVtzQdnnMNmkdI%2FVpp51lwP17n6M"
},
"url": "https://postman-echo.com/get?foo1=bar11&foo2=bar21&sum_v=3"
}
yaml
extract:
foo3: "body.args.foo2"
pytest
- 先调用extract()方法,然后调用with_jmespath(“jmespath提取变量值”,“变量名”)
.extract()
.with_jmespath("body.args.foo2", "foo3")
validate 校验结果
- 格式: - 运算符: [jmespath表达式, expected_value, message]
- jmespath: jmespath表达式
- expected_value: 指定期望值或变量,也可以调用方法
- message(可选): 用于描述断言失败原因
- 运算符
- equal: 等于
- contained_by: 实际结果是否被包含在预期结果中
- contains: 预期结果是否被包含在实际结果中
- endswith: 以…结尾
- greater_or_equals: 大于等于
- greater_than: 大于
- length_equal: 长度等于
- length_greater_or_equals: 长度大于等于
- length_greater_than: 长度大于
- length_less_or_equals: 长度小于等于
- length_less_than: 长度小于
- less_or_equals: 小于等于
- less_than: 小于
- not_equal: 不等于
- regex_match: 字符串是否符合正则表达式匹配规则
- startswith: 以…开头
- string_equals: 字符串相等
- type_match: 类型是否匹配
- 场景:想要校验响应状态码和响应体中foo1的返回值
yaml
validate:
- eq: ["status_code", 200]
- eq: ["body.args.foo1", "bar11"] # jmespath提取变量值,期望值
pytest
- 先调用validate(),在调用assert_equal(‘实际值’,‘期望值’)
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.args.foo1", "bar11")
说明
- 提取响应状态码,可直接status_code
- 提取响应值 body.args.foo1 , 其中body是固定值,如下图为响应体