做接口测试时,传给后端的数据,需要根据API文档做一下数据格式的校验。后端返回给前端的数据也需要根据API文档做数据格式的校验,此时使用JsonSchema来验证数据结构。官方文档。
python jsonschema
安装,基本使用参见文档
类型校验,要查看其它的详细文档,注意上方的下拉选择
必填项
使用required来指定必有项
1 2 3 4 5 6 7 8 9
| { "type": "object", "properties": { "street_address": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" } }, "required": ["street_address", "city", "state"] }
|
需要查找某个属性时,记得使用搜索框
enum规定范围
1 2 3 4
| { "type": "string", "enum": ["NW", "NE", "SW", "SE"] }
|
如果指定string为固定值,enum只写一个值
1 2 3 4
| { "type": "string", "enum": ["NW"] }
|
使用组合
anyOf, allOf, oneOf, not组合规则方便我们组合出更严格的校验规则,另外还提供了definitions方式命名一套复杂的校验方案,使用时用$ref引用这个命名的校验方案(数据模式复用)。
allOf:取并集
1 2 3 4 5 6
| { "allOf": [ { "type": "string" }, { "maxLength": 5 } ] }
|
"short"符合,too long不符合。
oneOf: 满足且只满足一个, 多个满足要报错。
anyOf:满足任意一个 Schema 即可
定义复用snippet
使用definitions,如下,定义了一个需要的复用的address的schema
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "definitions": { "address": { "type": "object", "properties": { "street_address": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" } }, "required": ["street_address", "city", "state"] } } }
|
使用snippet
使用ref(JSON Pointer),使用刚刚定义的address
1
| { "$ref": "#/definitions/address" }
|
#指向文档根目录
definitions:找到key未definitions的值
- 找到definitions中key未address的值
$ref可以使用相对URI,也可以使用绝对URI,如果要将definitions放在单独的文件中,可以使用相对URI,如{ "$ref": "definitions.json#/address" }
使用python变量复用
json-schema本身的这个很难用,直接使用python中的变量来复用:
a.py
b.py
python开始验证
1 2
| from jsonschema import validate, ValidationError validate(data, schema)
|
错误集锦
python使用jsonscheme引用ref报错
1
| unknown url type definitions
|
将definitions放在当前的文档中,没有问题,放在外部文件中,根据官方文档的说明:

main.py文件
1 2 3 4 5 6 7 8 9 10 11
| from jsonschema import validate
a = { "type": "object", "required": ["shipping_address"], "properties": { "shipping_address": {"$ref": "definitions.json#/address"} } } ins = {"billing_address": 1, "shipping_address": 2} validate(ins, a)
|
definitions.json文件
1 2 3 4 5 6 7 8 9 10 11
| { "adress": { "type": "object", "properties": { "street_address": {"type": "string"}, "city": {"type": "string"}, "state": {"type": "string"} }, "required": ["street_address", "city", "state"] } }
|
解决使用file
main.py文件
1 2 3 4 5 6 7 8 9 10 11
| from jsonschema import validate
a = { "type": "object", "required": ["shipping_address"], "properties": { "shipping_address": {"$ref": "file:address.json"} } } ins = {"billing_address": 1, "shipping_address": 2} validate(ins, a)
|
这里的file使用的是相对路径,相对当前运行目录。
address.json文件
1 2 3 4 5 6 7 8 9
| { "type": "object", "properties": { "street_address": {"type": "string"}, "city": {"type": "string"}, "state": {"type": "string"} }, "required": ["street_address", "city", "state"] }
|
json文件中不能再使用ref,找不到,仍然会报错找不到URL
这里需要一个definition需要写一个单独的文件,暂时没有找到多个definition写到一个json文件中的引用方法。
多层嵌套
丢弃使用xxx.json文件,使用py的dict做为小片段,为了解决多层嵌套。
a.py
1 2 3
| address = {"street": "Ls", "sv", "Anni"} b = {"name": "Ane", "address": address} a = {"a": 1, "b": b}
|