python三:jsonpath-rw管理Json对象

前提:接口自动化测试中,存在依赖情况:test_02的某个请求参数的值,需要依赖test_01返回结果中某个字段的数据,所以就先需要拿到返回数据中特定字段的值。这里使用到python中jsonpath-rw库

json数据检索与定位之jsonPath类库

转载请注明出处:

1.下载安装

by:授客
QQ:1033553122

 

pip
install jsonpath-rw

实践环境

前言:上篇文章python3+requests+unittest:接口自动化测试(一): ,已经介绍了基于unittest框架的实现接口自动化,但是也存在一些问题,比如最明显的测试数据和业务没有区分开,接口用例不便于管理等,所以又对此修改完善。接下来主要是介绍该套接口自动化框架的设计到实现,参考代码的git地址:

2.导入

win7
64

 

from
jsonpath_rw import jsonpath,parse

Python
3.4.0

1.代码框架展示

3.例子介绍

jsonpath_ng-1.4.3-py2.py3-none-any.whl

 图片 1

1.返回的match数据,但我们想要的是value数据

下载地址:

(1)case:存放测试用例数据的,比如请求类型get/post、请求url、请求header、请求数据等;

jsonpath_expr = parse('foo[*].baz')
data = {'foo': [{'baz': 'news'}, {'baz': 'music'}]}
print([match for match in jsonpath_expr.find(data)])

运行结果:
[DatumInContext(value='news', path=Fields('baz'), context=DatumInContext(value={'baz': 'news'}, path=<jsonpath_rw.jsonpath.Index object at 0x025CA850>, context=DatumInContext(value=[{'baz': 'news'}, {'baz': 'music'}], path=Fields('foo'), context=DatumInContext(value={'foo': [{'baz': 'news'}, {'baz': 'music'}]}, path=This(), context=None)))), DatumInContext(value='music', path=Fields('baz'), context=DatumInContext(value={'baz': 'music'}, path=<jsonpath_rw.jsonpath.Index object at 0x025CA770>, context=DatumInContext(value=[{'baz': 'news'}, {'baz': 'music'}], path=Fields('foo'), context=DatumInContext(value={'foo': [{'baz': 'news'}, {'baz': 'music'}]}, path=This(), context=None))))]

(2)data:获取excel文件中相应数据的方法封装,获取excel中对应表格内的数据,excel的行列数据等:get_data.py;判断用例之间是否存在依赖关系并获取依赖数据:dependent_data.py;初始化excel文件:data_config.py;

2.获取匹配的数据match.value

(3)dataconfig:存放请求中涉及到的header、data、cookies等数据;

jsonpath_expr = parse('foo[*].baz')
data = {'foo': [{'baz': 'news'}, {'baz': 'music'}]}
print([match.value for match in jsonpath_expr.find(data)])
运行结果:
['news', 'music']

使用详解

(4)log:存放测试完成之后生成的日志文件,可以查看日志定位问题;

3.match.value返回数据是一个list,我们要获取特定的值

官方实例

>>>
from jsonpath_ng import jsonpath, parse

>>>
jsonpath_expr = parse(‘foo[*].baz’)

#
提取值

>>>
[match.value for match in jsonpath_expr.find({‘foo’:[{‘baz’:1},
{‘baz’:2}]})]

[1,
2]

#
获取匹配值对应的路径

>>>
[str(match.full_path) for match in jsonpath_expr.find({‘foo’:
[{‘baz’: 1}, {‘baz’: 2}]})]

[‘foo.[0].baz’,
‘foo.[1].baz’]

#
自动提供id

>>>
[match.value for match in parse(‘foo[*].id’).find({‘foo’: [{‘id’:
‘bizzle’}, {‘baz’: 3}]})]

[‘bizzle’]

>>>
jsonpath.auto_id_field = ‘id’

>>>
[match.value for match in parse(‘foo[*].id’).find({‘foo’: [{‘id’:
‘bizzle’}, {‘baz’: 3}]})]

[‘foo.bizzle’,
‘foo.[1]’]

#
扩展功能之一 命名操作符 `parent`

>>>
[match.value for match in parse(‘a.*.b.`parent`.c’).find({‘a’: {‘x’:
{‘b’: 1, ‘c’: ‘number one’}, ‘y’: {‘b’: 2, ‘c’: ‘number
two’}}})]

[‘number
one’, ‘number two’]

>>>
[‘number two’, ‘number one’]

(5)main:脚本执行的主函数run_test.py

jsonpath_expr = parse('foo[*].baz')
data = {'foo': [{'baz': 'news'}, {'baz': 'music'}]}
print([match.value for match in jsonpath_expr.find(data)][0])

运行结果:
news

使用扩展的解析器

好处是有更强大的扩展功能

>>>
from jsonpath_ng.ext import parse

>>>
jsonpath_expr = parse(‘foo[*].baz’)

(6)util:通用方法的封装,各种不同断言方式common_assert.py;对excel文件的读写操作operation_excel.py;从请求返回数据中拿取数据作为下一个接口的请求header数据operation_header.py;从json文件中拿取想要的数据operation_json.py;将接口自动化过程中的相关日志输出到log.txt中print_log.py;根据请求类型的不同执行对应的get/post方法runmethod.py;将测试结果以邮件形式发送给相关人员send_mail.py。

 

jsonpath 语法

基础语法(Atomic
expressions)

$
根对象

`this`
当前对象

`foo`
More generally, this syntax allows “named operators” to extend JSONPath
is arbitrary ways

field
指定具体的字段

[
field ] 同field

[
idx ] 数组访问 Array access, described below (this is always
unambiguous with field access)

 

例子

2.代码实现说明

获取根对象

>>>
parse.find({‘key1’:{‘id’: 1}, ‘key2’:{‘id’: 2}, ‘key3’:[{‘id’:3},
{‘name’:’shouke’}]})

[DatumInContext(value={‘key2’:
{‘id’: 2}, ‘key3’: [{‘id’: 3}, {‘name’: ‘shouke’}], ‘key1’: {‘id’:
1}}, path=Root(), context=None)]

>>>
[match.value for match in parse.find({‘key1’:{‘id’: 1}, ‘key2’:{‘id’:
2}, ‘key3’:[{‘id’:3}, {‘name’:’shouke’}]})]

[{‘key2’:
{‘id’: 2}, ‘key3’: [{‘id’: 3}, {‘name’: ‘shouke’}], ‘key1’: {‘id’:
1}}]

(1)首先看下用例数据

获取一级键对应的值

>>>
[match.value for match in parse.find({‘key1’:{‘id’: 1}, ‘key2’:{‘id’:
2}, ‘key3’:[{‘id’:3}, {‘name’:’shouke’}]})]

[{‘id’:
1}]

>>>
[match.value for match in parse.find({‘key1’:{‘id’: 1}, ‘key2’:{‘id’:
2}, ‘key3’:[{‘id’:3}, {‘name’:’shouke’}]})]

[{‘id’:
1}]

#
注意:单独使用 filed、 [filed]
语法,field仅支持字典的一级键

[{‘key2’:
{‘id’: 2}, ‘key3’: [{‘id’: 3}, {‘name’: ‘shouke’}], ‘key1’: {‘id’:
1}}]

>>>
[match.value for match in parse.find({‘key1’:{‘id’: 1}, ‘key2’:{‘id’:
2}, ‘key3’:[{‘id’:3}, {‘name’:’shouke’}]})]

[]

#
注意:单独使用 filed、 [filed]
语法,根对象必须是字典,不能是数组

>>>
[match.value for match in parse.find([{‘key1’:{‘id’: 1}, ‘key2’:{‘id’:
2}, ‘key3’:[{‘id’:3}, {‘name’:’shouke’}]}])]

[]

说明:该用例只是用来覆盖一些接口场景而测试使用的,有兴趣的可以参考源码用自己项目的真实数据来实现

数组访问

>>>
[match.value for match in parse.find([{‘key1’:{‘id’: 1}, ‘key2’:{‘id’:
2}, ‘key3’:[{‘id’:3}, {‘name’:’shouke’}]}])]

[{‘key2’:
{‘id’: 2}, ‘key3’: [{‘id’: 3}, {‘name’: ‘shouke’}], ‘key1’: {‘id’:
1}}]

 图片 2

jsonpath操作符

jsonpath1
. jsonpath2 匹配jsonpath2,并且父节点匹配jsonpath1的所有节点(All nodes
matched by jsonpath2 starting at any node matching jsonpath1)
注意:仅针对字典可用

注:有无空格不影响,比如jsonpath1.jsonpath2
下同

jsonpath
[ whatever ]
如果是字典,同jsonpath.whatever,如果是数组,则表示按索引访问数组

jsonpath1
.. jsonpath2
匹配jsonpath2,并且由匹配jsonpath1的父节点派生的所有节点

jsonpath1
where jsonpath2
匹配jsonpath1并且携带一个匹配jsonpath2直接子节点的所有节点(Any nodes
matching jsonpath1 with a child matching jsonpath2)

jsonpath1
| jsonpath2
匹配jsonpath1,或者jsonpath2的所有节点的集合(注:有时候结果似乎和描述不符,具体见例子

 先判断是否执行:如果yes,执行该条用例;如果no,直接跳过该条用例。

例子

执行用例:获取用例的url、请求类型、请求头header、请求数据,request.get/post执行该条接口用例。

发表评论

电子邮件地址不会被公开。 必填项已用*标注