前言
- 本篇来学习如何使用JMESPath在 extract和 validate 的时候提取响应报文中的值
JMESPath简介
python中使用jmespath
pip install jmespath
import jmespath
value = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
print(value)
import jmespath
expression = jmespath.compile('foo.bar')
a = expression.search({'foo': {'bar': 'baz'}})
b = expression.search({'foo': {'bar': 'other'}})
print(a)
print(b)
基本表达式
- 字典取值,根据key获取value
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/8a321cfadcd4e7669c40009c12737417.png)
- 嵌套字典取值,一层一层取值
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e99bd973e8ef42375f196f6639ea3f5c.png)
- list根据索引取值,索引从0开始
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/296fadd0127c29fa2ec748fa2e898acf.png)
- dict 嵌套list取值
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/7e64975fac5390c71200288ada184485.png)
切片
- list可以使用切片取值,和python语法一致: 一般形式是[start:stop:step]
- 取值0-4,使用[0,5] ,不包含结束索引的值
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a8eb7a5ede9c7e9f2af81defd92bd56b.png)
- 省略开始索引,表示从索引 0 开始取值
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/eebaec90928b0a1e5bd1341dd6792283.png)
- 省略始末索引表示取索引,第三个值为步长
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1a87498c304c9cd4323abe05075095e4.png)
- 反转list [::-1]
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/dfa4e07b3e2e9e6bad3fece6c633d8fb.png)
通配符*的使用
- 取出列表中所有的 first 对应的名称 people[*].first
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/eccfa0ddda0cefacd94b83ed401360cb.png)
- 取出列表中前 2 个 first 对应的名称 people[:2].first
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5eb44eacd8987456a0ce09d733e7f1b3.png)
- 取出 ops 对象的任意属性对应的numArgs ops.*.numArgs
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/cbf238a62ecfe2467b7b1e75603541ef.png)
过滤器使用
- 过滤器表达式是为数组定义的,其一般形式为 [? <表达式> <比较器> <表达式>]
- 常用的比较表达式可以使用 ==, !=, <, <=, >, > =
- 假设我们有一个机器列表,每个机器都有一个名称和一个 状态。我们想要所有正在运行的机器的名称
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/df1cde64b3cb7b756023224f884a077f.png)
管道表达式
- 如果查询的结果是一个list,如果我想取出结果里面的第一个可以使用管道符 |
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/20c37fdd88a6f15a7351d742023a9870.png)
多选
- 可以创建JSON文档中不存在的元素
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/71cc244f90cff60f818f761b906a2890.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c17d86eb113893175bbf5b80a324d014.png)
函数的使用
- 结果的数量
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a8559f0623e5db292e67b09c63bdc4cd.png)
- 打印age最大的name
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2a1e9e58ffc71d9a44cd7f16d5db40fa.png)
- 函数与过滤器结合使用
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0111bf61478d617a69f1064d77a0de23.png)
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"]
pytest
- 先调用validate(),在调用assert_equal(‘实际值’,‘期望值’)
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.args.foo1", "bar11")
说明
- 提取响应状态码,可直接status_code
- 提取响应值 body.args.foo1 , 其中body是固定值,如下图为响应体
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5cb8d3a28b16c44781d2d56988772cb9.png)