接口自动化中的jsonSchema及契约测试

Python publisher01 23℃

目录

  • 场景介绍:接口自动化及契约测试
  • jsonschema介绍
  • 契约测试实现步骤及Demo
  • jsonschema编写规则及例子-swagger
  • 接口实战的例子
  • 契约测试应用

场景应用

一个 基于saas的跨境电商ERP系统的物流模块,要对接了多个物流公司,不同的物流公司有不同的IT团队,使用不同的技术实现方法和不同的接口提供方式。而测试人员在每一次发版之前和之后几乎都是崩溃的,因为至少需要对30多家物流公司上百种物流方式进行全覆盖测试。
解决方案:接口的自动化测试
接口的变更来源于对方修改了他们之前和我们说好的接口而没有通知到我们。由此引起了无数的血雨腥风和线上缺陷
接口的变更应对方案:契约测试

1、契约测试

契约测试是验证服务的Provider是否按照期望的方式与服务的Consumer进行交互,简单的说是Consumer与Provider两者之间的集成。
通俗一点的说法就是在以上我们公司遇到的场景里面,我们和物流公司之间先定一个契约,然后我们可以定期的发送请求去检查这个契约,如果发送的请求不通过就表示契约有变。
鉴于现在好多的系统利用Json数据格式来进行数据的传输,考虑用jsonschema来解决这个问题。

2、jsonschema介绍

  • JSON Schema指的是数据交换中的一种虚拟的“合同”。
  • https://pypi.org/project/jsonschema/
  • JSON验证器负责验证语法错误,JSON Schema负责提供一致性检验。
  • 完全支持 Draft 7Draft 6Draft 4Draft 3
  • 延迟验证,可以迭代地报告所有验证错误。
  • 可以以编程方式查询哪些属性或项验证失败。

2.1、jsonschema相关资料

3、契约测试实现步骤

pip install jsonschema

申明一个Schema(此处的Schema可由上面的在线转换而来)
调用Valid函数,如果得到的值不出错,则运行时不会抛出异常
导入jsonschema及验证:

pip install jsonschema
from jsonschema import validate

声明你接口的schema(规范合同):类型,属性,属性的限制等

schema = {"type": "object", "properties": {"price": {"type": "number"}, "name": {"type": "string"}}}

验证你要传递的数据(实例)是否符合要求

validate(instance={"name": "Eggs", "price": 34.99}, schema=schema)
validate(instance={"name": "Eggs", "price": "34.99"}, schema=schema)

例1

from jsonschema import validate
schema = {"items": {"type": "boolean"},  "minItems": 2}
validate([True,False],schema=schema)

例2

from jsonschema.validators import Draft4Validator
# schema = {"items": {"type": "boolean"},  "minItems": 2}
schema = {'format': 'date', 'type': 'string', 'maxLength': 10}
validator = Draft4Validator(schema=schema)
validator.validate('2019-05-01')
validator.validate('2019/05/01')
validator.validate('2019050100')
validator.validate('2019年5月29日')
validator.validate('2019-05sf')
validator.validate(2019050100000)

接口自动化代码

schema2.json文件来自swagger官网导出的
可以自行裁剪

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "The Root Schema",
  "required": [
    "id",
    "category",
    "name",
    "photoUrls",
    "tags",
    "status"
  ],
  "properties": {
    "id": {
      "$id": "#/properties/id",
      "type": "string",
      "title": "The Id Schema",
      "default": 0,
      "examples": [
        2
      ]
    },
    "category": {
      "$id": "#/properties/category",
      "type": "object",
      "title": "The Category Schema",
      "required": [
        "id",
        "name"
      ],
      "properties": {
        "id": {
          "$id": "#/properties/category/properties/id",
          "type": "integer",
          "title": "The Id Schema",
          "default": 0,
          "examples": [
            2
          ]
        },
        "name": {
          "$id": "#/properties/category/properties/name",
          "type": "string",
          "title": "The Name Schema",
          "default": "",
          "examples": [
            "Something2"
          ],
          "pattern": "^(.*)$"
        }
      }
    },
    "name": {
      "$id": "#/properties/name",
      "type": "string",
      "title": "The Name Schema",
      "default": "",
      "examples": [
        "Something2"
      ],
      "pattern": "^(.*)$"
    },
    "photoUrls": {
      "$id": "#/properties/photoUrls",
      "type": "array",
      "title": "The Photourls Schema",
      "items": {
        "$id": "#/properties/photoUrls/items",
        "type": "string",
        "title": "The Items Schema",
        "default": "",
        "examples": [
          ""
        ],
        "pattern": "^(.*)$"
      }
    },
    "tags": {
      "$id": "#/properties/tags",
      "type": "array",
      "title": "The Tags Schema",
      "items": {
        "$id": "#/properties/tags/items",
        "type": "object",
        "title": "The Items Schema",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "$id": "#/properties/tags/items/properties/id",
            "type": "integer",
            "title": "The Id Schema",
            "default": 0,
            "examples": [
              2
            ]
          },
          "name": {
            "$id": "#/properties/tags/items/properties/name",
            "type": "string",
            "title": "The Name Schema",
            "default": "",
            "examples": [
              "Something2"
            ],
            "pattern": "^(.*)$"
          }
        }
      }
    },
    "status": {
      "$id": "#/properties/status",
      "type": "string",
      "title": "The Status Schema",
      "default": "",
      "examples": [
        "123"
      ],
      "pattern": "^(.*)$"
    }
  }
}

测试代码:
第一个方法是验证契约的
第二个是正常的业务接口

import requests
import pytest
import json
from jsonschema.validators import Draft7Validator
def addviladator(respose_data):
    with open("schema2.json", 'r') as f:
        dict_schema = json.load(f)
    va = Draft7Validator(dict_schema)
    va.validate(respose_data)
def test_search_by_id():
    url = 'https://petstore.swagger.io/v2/pet/1'
    res = requests.get(url=url)
    respose_data = res.json()
    print(respose_data)
    assert res.status_code == 200
    assert respose_data['name'] == '9YZQCGVJM8'
    assert res.elapsed.total_seconds() <= 3
    addviladator(respose_data)
if __name__ == '__main__':
    pytest.main(['-s', 'test_swaggeruidemo6.py'])

转载请注明:Python量化投资 » 接口自动化中的jsonSchema及契约测试

喜欢 (0)or分享 (0)