美文网首页程序员
Django的主体功能-接口结构体校验(八)

Django的主体功能-接口结构体校验(八)

作者: 测试游记 | 来源:发表于2019-03-03 13:09 被阅读7次

接口结构体校验的方式

纯编码形式的校验

一般常规的接口返回值校验需要把需要校验的字段逐个进行断言判断,这样进行有很大的编码工作量,显然不适用于接口测试平台。可以看一下例子:

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"

一个接口的返回值中如果有5个关键值就需要写5句断言。

jsonschema的方式

所以本次打算采用jsonschema的方式进行接口结构的校验。

jsonschema是描述你的JSON数据格式;JSON模式(应用程序/模式+ JSON)有多种用途,其中之一就是实例验证。验证过程可以是交互式或非交互式的。例如,应用程序可以使用JSON模式来构建用户界面使互动的内容生成除了用户输入检查或验证各种来源获取的数据。
Json Schema 快速入门https://blog.csdn.net/silence_xiao/article/details/81303935

具体的编写规则请自行查阅相关文档。
JsonSchema相当于一种契约测试,约定一个约束,如果符合要求则通过,如果不符合就不通过。

契约测试https://www.jianshu.com/p/ec40734c872a

具体优势,请自行体会吧,毕竟谁断言谁知道。

JsonSchema自动生成

虽然我们的要求应该是使用平台的人员传入一个自行编写的JsonSchema,然后我们进行结果的比对。但是这样的学习成本过高,并不很符合实际。所以这个契约的生成就需要进行一定的协助。
设计的思路为:用户传入一个认为正确的接口返回值,平台进行初步的类别判断并询问是否需要增加每个key值的约束。例如一个typenumber的对象,是否需要增加最大值最小值的校验。
现成的jsonschema转换器:https://jsonschema.net/#/
不过没有找到源码,只能自己实现一个了。
首先是格式的校验

def to_jsonschema(self, json_data, result):
    '''
    递归生成jsonschema
    '''
    if isinstance(json_data, dict):
        is_null = True
        result.append('{')
        result.append("'type': 'object',")
        result.append("'additionalProperties': 'false',")  # 不允许添加任何其他属性。
        result.append("'required':[],")  # 必需属性,先留空
        result.append("'properties': {")
        for k, v in json_data.items():
            is_null = False
            result.append("'%s':" % k)
            self.to_jsonschema(v, result)
            result.append(',')
        if not is_null:
            result.pop()
        result.append('}')
        result.append('}')
    elif isinstance(json_data, list):
        result.append('{')
        result.append("'type': 'array',")
        result.append("'items': ")
        self.to_jsonschema(json_data[0], result)
        result.append('}')
    elif isinstance(json_data, float):
        result.append("{")
        result.append("'type': 'number'")
        result.append('}')
    elif isinstance(json_data, int):
        result.append("{")
        result.append("'type': 'integer'")
        result.append('}')
    elif isinstance(json_data, str):
        result.append("{")
        if json_data.upper() in ("TRUE", "FALSE"):
            result.append("'type': 'boolean'")
        else:
            result.append("'type': 'string'")
        result.append('}')
    return "".join(result)

覆盖了:object,array,number,boolean,string
下面补全required和增加限制条件

def complement_required(self, jsonschema_dict):
    """
    补全必需属性
    """
    if isinstance(jsonschema_dict, dict):
        for item, value in jsonschema_dict.items():
            if value == 'object':
                properties = jsonschema_dict.get("properties")
                if isinstance(properties, dict):
                    for i, j in properties.items():
                        if j.get("type") in ("integer", "number", "string"):
                            self.complement_limit(i, j)
                        jsonschema_dict['required'].append(i)
                        if isinstance(j, dict) and j.get('type') == "object":
                            self.complement_required(j)
    elif isinstance(jsonschema_dict, list):
        for i in jsonschema_dict:
            self.complement_required(i)

def complement_limit(self, name, limit_dict):
    for i in self.limit:
        if name == i[0]:
            limit_type = i[1]
            if limit_type == 'integer' or limit_type == 'number':
                if i[2]:
                    limit_dict["maximum"] = i[2]
                if i[3]:
                    limit_dict["minimum"] = i[3]
                if i[4]:
                    limit_dict["enum"] = i[4]
                if i[5]:
                    limit_dict["multipleOf"] = i[5]
            elif limit_type == 'string':
                if i[2]:
                    limit_dict["maxLength"] = i[2]
                if i[3]:
                    limit_dict["minLength"] = i[3]
                if i[4]:
                    limit_dict["enum"] = i[4]
                if i[5]:
                    limit_dict["pattern"] = i[5]

进行简单的测试:

测试
可以看到基本符合要求了,后续页面/接口传入正确的东西就可以自动生成了。
里面对array的限制条件还有所欠缺,在后续补上。

代码请见:
https://github.com/zx490336534/Zxapitest/blob/master/utils/jsonschemaoperator.py
PS:欢迎关注我的公众号:

公众号

相关文章

  • Django的主体功能-接口结构体校验(八)

    接口结构体校验的方式 纯编码形式的校验 一般常规的接口返回值校验需要把需要校验的字段逐个进行断言判断,这样进行有很...

  • Api_God实现的全部功能汇总

    接口自动化功能: 一、接口功能校验 根据用例校验条件颗粒度来检查接口的返回情况 二、接口性能统计 针对接口响应时间...

  • C# 接口(interface)

    接口包含类或结构体可以实现的一组相关功能的定义。 实现接口的任何类或结构体都必须实现其所有成员。 接口无法实例化,...

  • 校验对象是否是结构体

    校验对象是否是结构体 目的 反射实现–>校验对象是否是结构体来自gin源码// ValidateStruct re...

  • 项目中用到的策略模式

    所在项目:产品中心功能点:数据校验接口该接口用于校验产品中心的数据的正确性,根据数据类型校验,如果是数字类型的数据...

  • 10. Go极简教程 Interface接口

    接口 interface 接口声明了方法集合 如果某个结构体实现了接口内的所有方法, 就可以把该结构体赋值给接口 ...

  • go - 学习笔记

    基础 函数 指针 结构体 接口 错误 协程 通道 基础 函数 指针 结构体 接口 错误 协程 通道

  • Springboot统一返回接口+统一异常处理+后端参数校验

    引入依赖 目录结构 1.统一返回接口 1.1 统一响应体定义 1.2 枚举状态码定义 2.实体类+参数校验 3.全...

  • Django 前后端分离 JWT 登录

    Django REST framework JWT 和登录功能实现前后分离token的方式做登录身份校验,jwt校...

  • Go语言接口知识点2 和 别名

    接口的断言 1. 如果结构体实现了某个接口你那么就可以使用接口类型来保存结构体变量, 那么该变量只能访问接口中的方...

网友评论

    本文标题:Django的主体功能-接口结构体校验(八)

    本文链接:https://www.haomeiwen.com/subject/ttrpuqtx.html