引子:
CC先生曾经参与过一个基于saas的跨境电商ERP系统,里面的坑很多,最坑的一个就是物流模块。因为在此模块中对接了多个物流公司。不同的物流公司有不同的IT团队,所以就有不同的技术实现方法和不同的接口提供方式。
当时开发人员几乎是针对于每一个物流公司都需要写单独的一套代码进行处理,而测试人员在每一次发版之前和之后几乎都是崩溃的,因为至少需要对30多家物流公司上百种物流方式进行全覆盖测试。
看到这里可能好多同学都想到了,那上接口的自动化测试呀!
紧接着问题就来了,很多时候的接口的变更来源于对方修改了他们之前和我们说好的接口而没有通知到我们。由此引起了无数的血雨腥风和线上缺陷,在此就不一一说明了。
最近看到TW在聊测试的时候老是提起一个话题:契约测试。
什么是契约测试呢?
契约测试是验证服务的Provider是否按照期望的方式与服务的Consumer进行交互,简单的说是Consumer与Provider两者之间的集成。
通俗一点的说法就是在以上我们公司遇到的场景里面,我们和物流公司之间先定一个契约,然后我们可以定期的发送请求去检查这个契约,如果发送的请求不通过就表示契约有变。
鉴于现在好多的系统利用Json数据格式来进行数据的传输,考虑用jsonschema来解决这个问题。
什么是JsonSchema?
JSON Schema指的是数据交换中的一种虚拟的“合同”。
JSON验证器负责验证语法错误,JSON Schema负责提供一致性检验。
在线jsonschema 转换:https://jsonschema.net/#/
将你的Json数据放入左边的输入框,“submit”以后→_→右边会自动的帮你生成对应的JSONSchema
在Python中如何实现?
之前验证接口的代码为:
import requests
#查询发布会接口
url = "http://127.0.0.1:8000/api/get_event_list/"
r = requests.get(url, params={'eid':'1'})
result = r.json()
print(result)
assert result['status'] == 200
assert result['message'] == "success"
assert result['data']['name'] == "锤子手机发布会"
assert result['data']['address'] == "成都"
assert result['data']['start_time'] == "2017-11-21T15:25:19"
此时当查询返回的值为上述值的时候,验证就可以顺利通过。
第一步:万年不变的 pip install 包名(此刻:pip install jsonschema)
第二步:导入包JSONschema
第三步:申明一个Schema
此处的Schema可由上面的在线转换而来)
第四步:调用Valid函数,如果得到的值不出错,则运行时不会抛出异常。
代码如下:
import requests
from jsonschema import validate
#查询发布会接口
url = "http://127.0.0.1:8000/api/get_event_list/"
r = requests.get(url, params={'eid':'1'})
myschema = {
"definitions": {},
"$schema": "http://json-schema.org/draft-06/schema#",
"$id": "http://example.com/example.json",
"type": "object",
"properties": {
"message": {
"$id": "/properties/message",
"type": "string",
"title": "The Message Schema.",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"success"
]
},
"data": {
"$id": "/properties/data",
"type": "object",
"properties": {
"address": {
"$id": "/properties/data/properties/address",
"type": "string",
"title": "The Address Schema.",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"\u6210\u90fd"
]
},
"eid": {
"$id": "/properties/data/properties/eid",
"type": "integer",
"title": "The Eid Schema.",
"description": "An explanation about the purpose of this instance.",
"default": 0,
"examples": [
1
]
},
"name": {
"$id": "/properties/data/properties/name",
"type": "string",
"title": "The Name Schema.",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"\u9524\u5b50\u624b\u673a\u53d1\u5e03\u4f1a"
]
},
"limit": {
"$id": "/properties/data/properties/limit",
"type": "integer",
"title": "The Limit Schema.",
"description": "An explanation about the purpose of this instance.",
"default": 0,
"examples": [
2000
]
},
"start_time": {
"$id": "/properties/data/properties/start_time",
"type": "string",
"title": "The Start_time Schema.",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"2017-11-21T15:25:19"
]
},
"status": {
"$id": "/properties/data/properties/status",
"type": "boolean",
"title": "The Status Schema.",
"description": "An explanation about the purpose of this instance."
}
}
},
"status": {
"$id": "/properties/status",
"type": "integer",
"title": "The Status Schema.",
"description": "An explanation about the purpose of this instance.",
"default": 0,
"examples": [
200
]
}
}
}
inputvalues = {'message': 'success', 'data': {'address': '成都', 'eid': 1, 'name': '锤子手机发布会', 'limit': 2000, 'start_time': '2017-11-21T15:25:19', 'status': True}, 'status': 200}
validate(inputvalues,schema=myschema)
上述仅为python中实现Json检验的方式,如果是xml格式的时候也可以用到xml校验。
参考:
http://www.jianshu.com/p/ec40734c872a