参考官网: https://python-jsonschema.readthedocs.io/en/stable/
应用场景
在做接口测试的时候,服务器返回的结果中的数据比较多,我们在进行数据验证的时候,可以对数据的主要自动进行验证。主要字段验证,使用之前的方式都可以实现(使用对应的Python基本类型中相关方法即可实现)
如果要对整个数据的类型进行验证,比如 服务器返回的结果
{"name" : "Eggs", "price" : 34.99}
name 字段是确定的, name的值为 字符串。但是name具体值不确定,
price 字段也是确定的, price的值为数字,但是具体值也不确定。
在接口测试过程中,要对具体的确定的部分进行必要断言。 使用 schema 方式进行断言。
可以声明 数据的类型
schema = {"type" : "object","properties" : {"price" : {"type" : "number"},"name" : {"type" : "string"},},}
通过声明类型的方式 对值进行断言。
安装包
pip install jsonschema
快速开始
将数据的类型定义为 schema 使用 jsonschema 进行验证。
main.py 文件
# 导入jsonschemafrom jsonschema import validate# 定义 schemaschema = {"type" : "object", # 类型为对象类型"properties" : { # 主要字段的属性"price" : {"type" : "number"}, # price 字段类型为 数字"name" : {"type" : "string"}, # name 字段的类型为 字符串},"required":["name","price"] # name, price 两个字段必须存在}def test_01():testdata = {"name":"apple","price":20}validate(instance=testdata,schema=schema)def test_02():"""执行失败:return:"""testdata = {"name":"banana","price":None # None 不是数字类型}validate(instance=testdata,schema=schema)def test_03():"""会报错, 字段 names 不存在:return:"""testdata = {"names":"apple","price":20.1}validate(instance=testdata,schema=schema)
使用 pytest 执行
pytest -s -v main.py

实际生产环境中
上面例子中的数据比较简单,在公司中的项目一个接口返回的数据,数据量可能会比较大,如何设置schema?
推荐使用一些在线工具生成对应的schame.
https://www.jsonschema.net/home (这个需要翻墙)
使用 https://tooltt.com/json2schema/ (这个可以直接使用)
在网站上设置必要的字段
将返回结果复制到网站中,可以自动生成对应得schema。
将对应的schema信息保存到文件中
schema.json
{"$schema": "http://json-schema.org/draft-07/schema","$id": "http://example.com/example.json","type": "object","required": ["resultCode","message","data"],"properties": {"resultCode": {"$id": "#/properties/resultCode","type": "integer"},"message": {"$id": "#/properties/message","type": "string"},"data": {"$id": "#/properties/data","type": "object","required": ["carousels","hotGoodses","newGoodses","recommendGoodses"],"properties": {"carousels": {"$id": "#/properties/data/properties/carousels","type": "array","items": {"$id": "#/properties/data/properties/carousels/items","anyOf": [{"$id": "#/properties/data/properties/carousels/items/anyOf/0","type": "object","required": ["carouselUrl","redirectUrl"],"properties": {"carouselUrl": {"$id": "#/properties/data/properties/carousels/items/anyOf/0/properties/carouselUrl","type": "string"},"redirectUrl": {"$id": "#/properties/data/properties/carousels/items/anyOf/0/properties/redirectUrl","type": "string"}}}]}},"hotGoodses": {"$id": "#/properties/data/properties/hotGoodses","type": "array","items": {"$id": "#/properties/data/properties/hotGoodses/items","anyOf": [{"$id": "#/properties/data/properties/hotGoodses/items/anyOf/0","type": "object","required": ["goodsId","goodsName","goodsIntro","goodsCoverImg","sellingPrice","tag"],"properties": {"goodsId": {"$id": "#/properties/data/properties/hotGoodses/items/anyOf/0/properties/goodsId","type": "integer"},"goodsName": {"$id": "#/properties/data/properties/hotGoodses/items/anyOf/0/properties/goodsName","type": "string"},"goodsIntro": {"$id": "#/properties/data/properties/hotGoodses/items/anyOf/0/properties/goodsIntro","type": "string"},"goodsCoverImg": {"$id": "#/properties/data/properties/hotGoodses/items/anyOf/0/properties/goodsCoverImg","type": "string"},"sellingPrice": {"$id": "#/properties/data/properties/hotGoodses/items/anyOf/0/properties/sellingPrice","type": "integer"},"tag": {"$id": "#/properties/data/properties/hotGoodses/items/anyOf/0/properties/tag","type": "string"}}}]}},"newGoodses": {"$id": "#/properties/data/properties/newGoodses","type": "array","items": {"$id": "#/properties/data/properties/newGoodses/items","anyOf": [{"$id": "#/properties/data/properties/newGoodses/items/anyOf/0","type": "object","required": ["goodsId","goodsName","goodsIntro","goodsCoverImg","sellingPrice","tag"],"properties": {"goodsId": {"$id": "#/properties/data/properties/newGoodses/items/anyOf/0/properties/goodsId","type": "integer"},"goodsName": {"$id": "#/properties/data/properties/newGoodses/items/anyOf/0/properties/goodsName","type": "string"},"goodsIntro": {"$id": "#/properties/data/properties/newGoodses/items/anyOf/0/properties/goodsIntro","type": "string"},"goodsCoverImg": {"$id": "#/properties/data/properties/newGoodses/items/anyOf/0/properties/goodsCoverImg","type": "string"},"sellingPrice": {"$id": "#/properties/data/properties/newGoodses/items/anyOf/0/properties/sellingPrice","type": "integer"},"tag": {"$id": "#/properties/data/properties/newGoodses/items/anyOf/0/properties/tag","type": "string"}}}]}},"recommendGoodses": {"$id": "#/properties/data/properties/recommendGoodses","type": "array","items": {"$id": "#/properties/data/properties/recommendGoodses/items","anyOf": [{"$id": "#/properties/data/properties/recommendGoodses/items/anyOf/0","type": "object","required": ["goodsId","goodsName","goodsIntro","goodsCoverImg","sellingPrice","tag"],"properties": {"goodsId": {"$id": "#/properties/data/properties/recommendGoodses/items/anyOf/0/properties/goodsId","type": "integer"},"goodsName": {"$id": "#/properties/data/properties/recommendGoodses/items/anyOf/0/properties/goodsName","type": "string"},"goodsIntro": {"$id": "#/properties/data/properties/recommendGoodses/items/anyOf/0/properties/goodsIntro","type": "string"},"goodsCoverImg": {"$id": "#/properties/data/properties/recommendGoodses/items/anyOf/0/properties/goodsCoverImg","type": "string"},"sellingPrice": {"$id": "#/properties/data/properties/recommendGoodses/items/anyOf/0/properties/sellingPrice","type": "integer"},"tag": {"$id": "#/properties/data/properties/recommendGoodses/items/anyOf/0/properties/tag","type": "string"}}}]}}}}}}
编写python文件进行schema验证。
main.py
import requests
import json
from jsonschema import validate
# 读取json文件中的数据
with open('./schame.json',mode='r') as file:
schemadata = json.load(file)
def test_index_page():
r = requests.get("http://49.233.108.117:28019/api/v1/index-infos")
# 添加对服务器返回的结果 进行schema 断言
validate(instance=r.json(),schema=schemadata)
执行
pytest -s -v main.py
面试问题
- 你在做接口的时候是如何进行断言的?
- 首先对基本返回状态码进行断言
- 同时根据接口的业务针对主要返回结果进行断言。
- 也要对服务器返回结果的数据类型进行断言,数据类型使用的是 jsonschema 进行断言。
