jsonpath
jsonpath是一种信息抽取类库, 是从json文档中抽取指定信息的工具
jsonpath对于json来说, 相当于xpath对于xml
jsonpath和xpath语法对比
json结构信息, 可读性高, 复杂度低, 非常容易匹配, 下表对应了xpath的用法
xpath
jsonpath
描述
/
$
根节点
.
@
现行节点
/
.or[]
取子节点
..
n/a
父元素
//
..
递归下降,所有符合条件的
*
*
通配符, 表示所有元素
@
n/a
属性访问字符
[]
[]
子元素操作符
[,]
数组索引
n/a
[start:end:step]
数组分割
[]
?()
应用过滤表达式
jsonpath例子
{
“store”: {
“book”: [
{
“category”: “reference”,
“author”: “Nigel Rees”,
“title”: “Sayings of the Century”,
“price”: 8.95
},
{
“category”: “fiction”,
“author”: “Evelyn Waugh”,
“title”: “Sword of Honour”,
“price”: 12.99
},
{
“category”: “fiction”,
“author”: “Herman Melville”,
“title”: “Moby Dick”,
“isbn”: “0-553-21311-3”,
“price”: 8.99
},
{
“category”: “fiction”,
“author”: “J. R. R. Tolkien”,
“title”: “The Lord of the Rings”,
“isbn”: “0-395-19395-8”,
“price”: 22.99
}
],
“bicycle”: {
“color”: “red”,
“price”: 19.95
}
},
“expensive”: 10
}
有这样一个json数据
XPath
JSONPath
结果
/store/book/author
$.store.book[*].author
所有书的作者
//author
$..author
所有的作者
/store/*
$.store.*
store的所有元素。所有的bookst和bicycle
/store//price
$.store..price
store里面所有东西的price
//book[3]
$..book[2]
第三个书
//book[last()]
$..book[(@.length-1)]
最后一本书
//book[position()<3]
..book[:2]
前面的两本书
//book[isbn]
$..book[?(@.isbn)]
过滤出所有的包含isbn的书
//book[price<10]
$..book[?(@.price<10)]
过滤出价格低于10的书。
//*
$..*
所有元素。
那么如何利用jsonpath进行接口测试?
通常我们校验接口有这样几种:
1. 判断字段值与预期是否相等
2.判断是否包含某字段
3.判断数据数量是否正确
4.判断数据格式
如果是数据格式校验, 个人认为可以用jsonschema, 既然要做到整体数据格式校验层了就应该做的完善了。后面会记录下如何用jsonschema来进行数据格式校验。
利用jsonschema对返回数据做整体校验(数据结构, 数据类型, 数据value等): https://www.cnblogs.com/dreamyu/p/9317721.html
import requests
import jsonpath
CHECK_TYPE = (
'equal',
'contains',
'data_size',
'data_type',
)
url = "http://www.lagou.com/lbs/getAllCitySearchLabels.json"
data1 = requests.get(url)
print(data1.json())
citylist = jsonpath.jsonpath(data1.json(), "$..[?(@.name=='安庆')]")
print(citylist)
# 例如我们要校验 parentId是否等于 541
check_dic = {
'key': 'parentId',
'check_type': 'equal',
'value': 541
}
# 在jsonpath中它是去找到所有符合path规则的数据, 会以list的形式返回,所以判断是否相等和是否包含其实是一样的, 只要在json中找到 key=value就会返回数据
def check_json(dic, data):
if dic['key'] and dic['check_type']:
key = dic['key']
check_type = dic['check_type']
if check_type == 'data_size':
expo = '$..%s' % key
json_data = jsonpath.jsonpath(data.json(), expo)
print('data_size: ' + str(len(json_data[0])))
return
json_data = get_json(dic, data)
if json_data:
print('pass')
print(json_data)
else:
print('false')
else:
print('check_dic有问题')
def get_json(dic, data):
# 判断value是int 还是str
if isinstance(dic['value'], int):
expo = "$..[?(@.%s==%s)]" % (dic['key'], dic['value'])
elif isinstance(dic['value'], str):
expo = "$..[?(@.%s=='%s')]" % (dic['key'], dic['value'])
json_data = jsonpath.jsonpath(data.json(), expo)
return json_data
check_json(check_dic, data1)