专栏首页测试游记Django的主体功能-接口结构体校验(八)

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

接口结构体校验的方式

纯编码形式的校验

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

 1import requests
 2
 3#查询发布会接口
 4url = "http://127.0.0.1:8000/api/get_event_list/"
 5
 6r = requests.get(url, params={'eid':'1'})
 7result = r.json()
 8print(result)
 9assert result['status'] == 200
10assert result['message'] == "success"
11assert result['data']['name'] == "锤子手机发布会"
12assert result['data']['address'] == "成都"
13assert 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/#/ 不过没有找到源码,只能自己实现一个了。 首先是格式的校验

 1def to_jsonschema(self, json_data, result):
 2    '''
 3    递归生成jsonschema
 4    '''
 5    if isinstance(json_data, dict):
 6        is_null = True
 7        result.append('{')
 8        result.append("'type': 'object',")
 9        result.append("'additionalProperties': 'false',")  # 不允许添加任何其他属性。
10        result.append("'required':[],")  # 必需属性,先留空
11        result.append("'properties': {")
12        for k, v in json_data.items():
13            is_null = False
14            result.append("'%s':" % k)
15            self.to_jsonschema(v, result)
16            result.append(',')
17        if not is_null:
18            result.pop()
19        result.append('}')
20        result.append('}')
21    elif isinstance(json_data, list):
22        result.append('{')
23        result.append("'type': 'array',")
24        result.append("'items': ")
25        self.to_jsonschema(json_data[0], result)
26        result.append('}')
27    elif isinstance(json_data, float):
28        result.append("{")
29        result.append("'type': 'number'")
30        result.append('}')
31    elif isinstance(json_data, int):
32        result.append("{")
33        result.append("'type': 'integer'")
34        result.append('}')
35    elif isinstance(json_data, str):
36        result.append("{")
37        if json_data.upper() in ("TRUE", "FALSE"):
38            result.append("'type': 'boolean'")
39        else:
40            result.append("'type': 'string'")
41        result.append('}')
42    return "".join(result)

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

 1def complement_required(self, jsonschema_dict):
 2    """
 3    补全必需属性
 4    """
 5    if isinstance(jsonschema_dict, dict):
 6        for item, value in jsonschema_dict.items():
 7            if value == 'object':
 8                properties = jsonschema_dict.get("properties")
 9                if isinstance(properties, dict):
10                    for i, j in properties.items():
11                        if j.get("type") in ("integer", "number", "string"):
12                            self.complement_limit(i, j)
13                        jsonschema_dict['required'].append(i)
14                        if isinstance(j, dict) and j.get('type') == "object":
15                            self.complement_required(j)
16    elif isinstance(jsonschema_dict, list):
17        for i in jsonschema_dict:
18            self.complement_required(i)
19
20def complement_limit(self, name, limit_dict):
21    for i in self.limit:
22        if name == i[0]:
23            limit_type = i[1]
24            if limit_type == 'integer' or limit_type == 'number':
25                if i[2]:
26                    limit_dict["maximum"] = i[2]
27                if i[3]:
28                    limit_dict["minimum"] = i[3]
29                if i[4]:
30                    limit_dict["enum"] = i[4]
31                if i[5]:
32                    limit_dict["multipleOf"] = i[5]
33            elif limit_type == 'string':
34                if i[2]:
35                    limit_dict["maxLength"] = i[2]
36                if i[3]:
37                    limit_dict["minLength"] = i[3]
38                if i[4]:
39                    limit_dict["enum"] = i[4]
40                if i[5]:
41                    limit_dict["pattern"] = i[5]

进行简单的测试:

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

本文分享自微信公众号 - 测试游记(zx94_11),作者:zx钟

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 《流畅的Python》第一章学习笔记

    比如 ['abc', 'def', 'ghi', 'abc'] 转换成 ['abc', '_1', 'ghi', '_3'] , 消除关键词 def 和重复字段...

    zx钟
  • ARTS第二周

    假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

    zx钟
  • 测试开发进阶(十二)

    ![鼠标放上去之后](../../../Library/Application Support/typora-user-images/image-2019083...

    zx钟
  • 基于maven+ssm的增删改查之前后端之间使用json进行交互(显示员工信息)

    首先是在EmployeeController.java中,新建一个返回json数据的方法,注销掉原有的getEmps方法。

    绝命生
  • 算法提高 9-2 文本加密

    问题描述   先编写函数EncryptChar,按照下述规则将给定的字符c转化(加密)为新的字符:”A”转化”B”,”B”转化为”C”,… …”Z”转化为”...

    AI那点小事
  • python学习(13)

    #coding=utf-8 result = [] for i in range(1,6): result.append(chr(97+i-1)+str(i))...

    py3study
  • 写一个 golang 风格的协程扩展

    Kotlin 的协程库 kotlinx.coroutines 当中有个比较常用的 async 函数,返回的 Deferred<T> 有个 await 方法,这个...

    bennyhuo
  • 小程序自动化测试总结

    微信小程序生态日益完善,很多小程序项目页面越来越多,结构越来越复杂,业务逻辑也更加多样。以腾讯课堂小程序为例,目前腾讯课堂小程序部分页面结构和不同业务场景下的表...

    IMWeb前端团队
  • 今天你用了吗?

    随着嵌入式开发的复杂化,靠手工去画状态图分析显然已经不合时宜,IAR的 visualSTATE 是一组基于状态机的高级嵌入式设计工具套件,专门用...

    用户1605515
  • 数值的整数次方

扫码关注云+社区

领取腾讯云代金券