前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用pydantic进行接口校验

使用pydantic进行接口校验

作者头像
zx钟
发布2021-12-02 12:36:03
1.2K0
发布2021-12-02 12:36:03
举报
文章被收录于专栏:测试游记测试游记

背景

在进行接口自动化测试的时候,只是校验「状态码」或者「部分字段」并不能很好的发现问题,有时候需要对字段的类型,关系进行校验。

之前尝试过使用JSON Schema来进行校验,但是语法上感觉比较变扭。这次尝试使用pydantic来进行校验

pydantic

https://pydantic-docs.helpmanual.io/

pydantic:使用 python 类型注释进行数据验证和设置管理。

安装

代码语言:javascript
复制
$ pip install pydantic

实例

请求接口

最近在测试一个「订单合流」的接口

该接口可以查询制定类型的订单

总共有19个类型的订单,用一个字典处理它的对应关系

代码语言:javascript
复制
biz_type_data = {
    1: "预约挂号",
    2: "问诊",
    3: "服务包",
    4: "追问包",
    5: "一病多问",
    6: "会员",
    7: "体检",
    8: "远程医疗",
    9: "处方",
    10: "专病",
    11: "商品",
    12: "处方药品",
    13: "会员拼团",
    14: "讲堂课程",
    15: "健康管家",
    16: "赞赏",
    17: "停诊保障",
    18: "检查检验",
    19: "心理体检",
}

该接口的请求参数为

代码语言:javascript
复制
data = {"q": "", "pageNo": 1, "pageSize": 10, "bizOrderTypes": [1]}

修改「bizOrderTypes」列表即可返回对应类型的订单

比如[1]就是返回「预约挂号」的订单

返回的内容类似:

代码语言:javascript
复制
{
  "code": "0",
  "flag": "0",
  "message": "成功",
  "retUrl": "",
  "pageNo": 1,
  "pageSize": 1000,
  "pageCount": 1,
  "recordCount": 20,
  "items": [
    {
      "bizNo": "202111171045333625",
      "bizCode": "",
      "bizName": "",
      "bizOrderType": 1,
      "bizOrderTypeName": "预约挂号",
      "bizType": 1,
      "bizTypeName": "普通预约单",
      "title": "",
      "num": 1,
      "dealAmount": 1,
      "bizStatus": 3,
      "bizStatusName": "待确认",
      "providerName": "",
      "gmtBizCreated": 1637311540000,
      "props": {
        "patientName": "钟鑫",
        "deptName": "神经外科",
        "docName": "卢来元懿",
        "insure": 0,
        "visitDate": 1637337600000,
        "docTitle": "国家专家",
        "hospitalName": "微医门诊部"
      }
    },
    {
      "bizNo": "202111171045333406",
      "bizCode": "",
      "bizName": "",
      "bizOrderType": 1,
      "bizOrderTypeName": "预约挂号",
      "bizType": 1,
      "bizTypeName": "普通预约单",
      "title": "",
      "num": 1,
      "dealAmount": 1000,
      "bizStatus": 2,
      "bizStatusName": "待就诊",
      "providerName": "",
      "gmtBizCreated": 1637311475000,
      "props": {
        "patientName": "钟鑫",
        "deptName": "妇科",
        "docName": "王涛",
        "insure": 0,
        "visitDate": 1637683200000,
        "docTitle": "主任医师",
        "hospitalName": "徐州市中医院"
      }
    }
  ],
  "errorInfo": "成功"
}

导入包

代码语言:javascript
复制
from typing import Union, List
from pydantic import BaseModel, validator
from datetime import date

编写类型校验

由于外部的内容是通用的页面处理,所以我们主要校验item中的内容

代码语言:javascript
复制
class new_order_list(BaseModel):
    bizNo: str
    bizCode: str = ""
    bizName: str = ""
    bizOrderType: int
    bizOrderTypeName: str
    bizType: int
    bizTypeName: str
    title: str = ""
    num: int
    dealAmount: int
    bizStatus: int
    bizStatusName: str
    providerName: str = ""
    gmtBizCreated: date
    props: dict
  • str表示内容应该为字符串
  • str = ""表示内容应该为字符串且默认为空
  • int表示内容应该为数字
  • dict表示内容应该为字典
  • data表示时间

Pydantic支持以下日期时间 类型:

  • datetime 字段可以是:
  • datetime, 现有datetime对象
  • intfloat,假定为 Unix 时间,即自 1970 年 1 月 1 日以来的秒数(如果 >=-2e10或 <= `2e10`)或毫秒(如果 <`-2e10`或 > 2e10
  • str,以下格式有效:
    • YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]]]
    • intfloat作为字符串(假设为 Unix 时间)
  • date 字段可以是:
  • date, 现有date对象
  • int或者float,见datetime
  • str,以下格式有效:
    • YYYY-MM-DD
    • int或者float,见datetime
  • time 字段可以是:
  • time, 现有time对象
  • str,以下格式有效:
    • HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]]]
  • timedelta 字段可以是:
  • timedelta, 现有timedelta对象
  • int或者float,假设为秒
  • str,以下格式有效:
    • [-][DD ][HH:MM]SS[.ffffff]
    • [±]P[DD]DT[HH]H[MM]M[SS]S (timedelta 的 ISO 8601 格式)

由于props不同订单返回的字典不一样,所以我们后面封装另一个类去校验它

编写内部逻辑校验

对于某些字段有专门的逻辑,所以我们编写一个biz_type_match函数去校验

代码语言:javascript
复制
@validator('bizType')
    def biz_type_match(cls, v, values, **kwargs):
        if "bizOrderType" in values and "bizTypeName" in values:
            if values["bizOrderType"] == 1:
                reg_type_name = ["普通预约单", "专病预约单"]
                if reg_type_name[v - 1] != values["bizTypeName"]:
                    raise ValueError('bizType与bizTypeName不一致')
        return v

这个函数中v表示装饰器装饰的内容,也就是bizType

values表示的返回的整个内容

所以我们就可以校验「bizTypeName」和「bizType」的对应关系了

编写子字典props校验

代码语言:javascript
复制
class bizType():
    class bizType1(BaseModel):
        """
        预约挂号
        """
    deptName: str  # 科室名称
    patientName: Union[str, None]  # 患者姓名 就诊人可以解绑,所以允许为空
    docName: str  # 医生姓名
    docTitle: str  # 医生职称
    visitDate: date  # 就诊日期时间戳
    hospitalName: str  # 医院名称
    insure: int  # 是否购买停诊保险 0否1是
  • Union表示运行多个类型,可以根据具体逻辑设计

使用

代码语言:javascript
复制
for i in response_data['items']:
    new_order_list(**i)
    obj = getattr(bizType, f'bizType{type_data[0]}')
    try:
        obj(**i['props'])
    except Exception as e:
        pytest.assume(False, f"Error:{e}")

将拿到的数据传入对应的类中,就会自动进行校验

其他

更多校验方式可以参考官网:https://pydantic-docs.helpmanual.io/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • pydantic
    • 安装
    • 实例
      • 请求接口
        • 导入包
          • 编写类型校验
            • 编写内部逻辑校验
              • 编写子字典props校验
                • 使用
                • 其他
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档