接口自动化全量字段校验

全量字段校验 jsonschema 校验接口返回响应结果的全部字段(更进一步的断言)校验内容:1)字段值2)字段名或字段类型校验流程:1)定义json语法校验格式2)比对接口实际响应数据是否符合json校验格式。 阅读详情

目录

前言:

一.背景

二.校验原则

三.快速使用

安装:

1.python 类契约使用

2.json 契约使用

3.python 类契约转 json 契约

4.根据响应结果自动生成 json 契约

说明:

四.基本匹配规则

1. Matcher 类

校验规则:值匹配

2. Like 类

校验规则:类型匹配

3. EachLike 类

校验规则:数组类型匹配

4. Term 类

校验规则:正则匹配

5. Enum 类

校验规则:枚举匹配

五.复杂规则匹配

1.{ {}}格式

2.[[]] 格式

3.{[]}格式

4.Like-Term 嵌套

5.Like-Matcher 嵌套

说明:

六.异常场景匹配

1.null 匹配

2.{}匹配

3.json 格式字符串匹配

4.key 不存在匹配

5.多类型匹配

6.非强制字段匹配

注意:异常匹配场景越多,代表接口数据格式越不规范

七.配合 unittest+requests 使用

八.优点总结


前言:

接口自动化全量字段校验是一种对接口进行安全性评估的测试方法。它主要针对接口的全量字段进行校验,以确保接口的安全性和稳定性。

一.背景

公司前端吐槽后台接口有时会更改返回的数据结构,返回的字段名与字段类型与接口文档不一致,希望有一个快速检测接口返回数据的所有字段名与字段类型的方法

以下方数据为例,要校验 data 数组中 dict 结构中的字段名与字段类型,可以写脚本遍历数据,但是由于每个接口返回的数据结构可能不一致,可能需要针对每个接口做不同的逻辑,所以需要一个比较通用的校验方法

{
    "msg": "success",
    "code": 0,
    "data": [{
            "type_id": 249,
            "name": "王者荣耀",
            "order_index": 1,
            "status": 1,
            "subtitle": " ",
            "game_name": "王者荣耀"
        }, {
            "type_id": 250,
            "name": "绝地求生",
            "order_index": 2,
            "status": 1,
            "subtitle": " ",
            "game_name": "绝地求生"
        }, {
            "type_id": 251,
            "name": "刺激战场",
            "order_index": 3,
            "status": 1,
            "subtitle": " ",
            "game_name": "刺激战场"
        }
    ]
}

​在研究了契约测试后,抽取pact-python部分代码,实现:自定义接口返回数据格式 (【契约定义】)-实际响应数据格式校验 (【契约校验】) 的功能

备注:这里的【契约】等同于接口响应数据结构


二.校验原则

1.实际返回字段名要严格等于或者含契约定义字段名(根据不同匹配模式来确定)
2.字段值可以值相等或类型相等

目标:对返回数据进行全量 (字段名 - 值/类型) 校验
契约定义方式:支持 python 类契约和 json 契约


三.快速使用

安装:

pip install pactverify

1.python 类契约使用

from pactverify.matchers import Matcher, Like, EachLike, Enum, Term, PactVerify

# 定义契约格式
expect_format = Matcher({
    'code': 0,  # code key存在,值相等,code==0
    'msg': 'success',  # msg key存在,值相等,msg=='success'
    # [{}]结构
    'data': EachLike({
        "type_id": 249,  # type_id key存在,值类型相等,type(type_id) == type(249)
        "name": "王者荣耀",  # name key存在,值类型相等,type(name) == type("王者荣耀")
    }),
    'type': Enum([11,22]),
    'list': EachLike(11,minimum=2)
})

# 实际返回数据
actual_data = {
    "msg": "success",
    "code": 1,
    'type': 12,
    "data": [{
        # type_id类型不匹配
        "type_id": '249',
        "name": "王者荣耀"
    }, {
        # 缺少name
        "type_id": 250,
    }, {
        # 比契约定义多index字段
        "type_id": 251,
        "name": "刺激战场",
        "index": 111
    }
    ],
    'list': [11]
}
# hard_mode默认为true,hard_mode = True时,实际返回key必须严格等于预期key;hard_mode = False时,实际返回key包含预期key即可
mPactVerify = PactVerify(expect_format, hard_mode=True)
# 校验实际返回数据
mPactVerify.verify(actual_data)
# 校验结果  False
print(mPactVerify.verify_result)
''' 校验错误信息
错误信息输出actual_key路径:root.data.0.name形式
root为根目录,dict类型拼接key,list类型拼接数组下标(从0开始)
{   
    # 实际key少于预期key错误
    'key_less_than_expect_error': ['root.data.1.name'],
    # 实际key多与预期key错误,只在hard_mode = True时才报该错误
    'key_more_than_expect_error': ['root.data.2.index'],
    # 值不匹配错误
    'value_not_match_error': [{
            'actual_key': 'root.code',
            'actual_value': 1,
            'expect_value': 0
        }
    ],
    # 类型不匹配错误
    'type_not_match_error': [{
            'actual_key': 'root.data.0.type_id',
            'actual_vaule': '249',
            'expect_type': 'int'
        }
    ],
    # 数组长度不匹配错误
    'list_len_not_match_error': [{
            'actual_key': 'root.list',
            'actual_len': 1,
            'min_len': 2
        }
    ],
    # 枚举不匹配错误
    'enum_not_match_error': [{
            'actual_key': 'root.type',
            'actual_value': 12,
            'expect_enum': [11, 22]
        }
    ]
}

'''
print(mPactVerify.verify_info)

2.json 契约使用

from pactverify.matchers import PactJsonVerify

# 定义json契约格式
expect_format = {
    '$Matcher': {
        'code': 0,  # code key存在,值相等,code==0
        'msg': 'success',  # msg key存在,值相等,msg=='success'
        # [{}]结构
        'data': {
            '$EachLike': {
                "type_id": 249,  # type_id key存在,值类型相等,type(type_id) == type(249)
                "name": "王者荣耀",  # name key存在,值类型相等,type(name) == type("王者荣耀")
            }},
        'type': {
            '$Enum': [11, 22]
        },
        'list': {
            '$EachLike': {
                # $values,$params形式传递额外参数
                '$values': 11,
                '$params': {
                    'minimum': 2
                }
            }
        }
    }
}

# 实际返回数据
actual_data = {
    "msg": "success",
    "code": 1,
    'type': 12,
    "data": [{
        # type_id类型不匹配
        "type_id": '249',
        "name": "王者荣耀"
    }, {
        # 缺少name
        "type_id": 250,
    }, {
        # 比契约定义多index字段
        "type_id": 251,
        "name": "刺激战场",
        "index": 111
    }
    ],
    'list': [11]
}
# hard_mode默认为true,hard_mode = True时,实际返回key必须严格等于预期key;hard_mode = False时,实际返回key包含预期key即可
# separator可自定义指定json关键字标识符,默认为$
mPactJsonVerify = PactJsonVerify(expect_format, hard_mode=True, separator='$')
# 校验实际返回数据
mPactJsonVerify.verify(actual_data)
# 校验结果  False
print(mPactJsonVerify.verify_result)
''' 校验错误信息
错误信息输出actual_key路径:root.data.0.name形式
root为根目录,dict类型拼接key,list类型拼接数组下标(从0开始)
{   
    # 实际key少于预期key错误
    'key_less_than_expect_error': ['root.data.1.name'],
    # 实际key多与预期key错误,只在hard_mode = True时才报该错误
    'key_more_than_expect_error': ['root.data.2.index'],
    # 值不匹配错误
    'value_not_match_error': [{
            'actual_key': 'root.code',
            'actual_value': 1,
            'expect_value': 0
        }
    ],
    # 类型不匹配错误
    'type_not_match_error': [{
            'actual_key': 'root.data.0.type_id',
            'actual_vaule': '249',
            'expect_type': 'int'
        }
    ],
    # 数组长度不匹配错误
    'list_len_not_match_error': [{
            'actual_key': 'root.list',
            'actual_len': 1,
            'min_len': 2
        }
    ],
    # 元祖不匹配错误
    'enum_not_match_error': [{
            'actual_key': 'root.type',
            'actual_value': 12,
            'expect_enum': [11, 22]
        }
    ]
}
'''
print(mPactJsonVerify.verify_info)

3.python 类契约转 json 契约

1、python类契约不带参数
# python类契约
expect_format = Like({'k1': 'v1'})
# json契约
expect_format_json = {
    '$Like': {'k1': 'v1'}
}

2、python类契约带参数
# python类契约
expect_format = Like({'k1': 'v1'}, nullable=True)
# json契约
expect_format_json = {
    '$Like': {
        # $values为契约类目标参
【测试】接口测试 下方图片同理,按照JSON格式解析。 阅读详情

相关推荐

从零到一:Mx_yolo本地训练与K210部署实战指南

本文详细介绍了从零开始进行Mx_yolo本地模型训练到K210部署的全流程实战指南。涵盖环境配置、数据准备、模型训练与调优、模型转换及K210部署等关键步骤,并提供了常见问题解决方案和性能优化技巧,帮助开发者高效完成AI模型在嵌入式设备的落地应用。

weixin_29081163的博客 241

安装部署 Guacamole 远程桌面网关

Guacamole 是Apache基金会提供的一组基于web的远程桌面访问工具,支持 VNC、RDP、SSH、 Telnet 等协议,支持远程透传音视频。

UsamaBinLaden6976498的专栏 1959

知识的定义与分类体系详解 - 从零基础到专业理解

知识的定义与分类体系详解 - 从零基础到专业理解

engchina的专栏 4347

Linux运维人,该醒醒了,2019年要变天了

外界都说运维只是处于被动低效率手工救火的状态,企业对其重视程度不高,提起运维很多人能联想到的字眼就有“苦逼”、“辛苦”、“加班”、“背锅”。在大数据、人工智能、容器技术的强力加持下,运维这个传统的技术工种已经从“机械劳动”这样的刻板印象中蜕变出来,成为了任何一家技术公司所必须依赖和大力投入的核心技术能力。 现在,运维人员的发展前景也开始让很多程序员眼羡,作为Linux运维人员的你:这一年,你的L...

qq_43083284的博客 1万+

halcon与c#联合编程实现相机控制+图像平移缩放+日志记录+缺陷检测+路径规划

halcon与c#联合编程实现相机控制+图像平移缩放+日志记录+缺陷检测+路径规划 前言 本人近期在工作中遇到需要对某场景下利用海康相机进行图像缺陷检测与对应路径规划。通过对海康相机示例代码进行吸收与借鉴,最终实现了对海康相机的控制,并增加HSmartWindowControl控件,实现图像的实时显示与平移缩放功能;通过listview+toolstrip实现日志显示与类型(提示、警告、错误)分类;同时自行编制算法实现对缺陷的识别以及缺陷外扩矩形范围内的路径规划。 1.日志记录 代码如下(示例):

weixin_37864926的博客 2715

Claude Code 常见安装失败问题与解决办法

摘要: Claude Code安装失败通常与环境、网络和权限问题有关,而非软件本身。主要误区包括:命令未识别(需检查PATH和终端重启)、网络连接失败(终端代理配置)、权限不足(系统安全限制)及账号认证问题。首次使用应避免复杂任务,建议从基础功能测试开始。快速自检可按终端重启→命令识别→网络→代理→权限→账号状态的顺序排查。理顺终端、网络和权限后,Claude Code运行将更稳定。 (150字)

sg_knight的专栏 6674

ABAP 平台注册 OAuth 2.0 Client 的完整实践指南(覆盖 Authorization Code、SAML Bearer 与 PKCE)

本文详述了在ABAP平台上注册入站OAuth 2.0 Client的关键技术和操作要点。文章面向SAP技术人员,系统梳理了前置条件(TLS/SSL、技术用户、授权对象)、配置路径(SOAUTH2事务)、授权类型差异(授权码、SAML Bearer、PKCE)等重要内容。特别强调入站与出站配置的区别,并提供了保密客户端和公有客户端的配置指引。文中所有事务码和参数均参考SAP官方文档,包含多个实用案例和权限配置建议,为ABAP系统作为OAuth 2.0授权服务器的实施提供全面指导。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 291

【人工智能时代】- 一键部署本地AI大模型

Ollama是一个开源项目,致力于简化大型语言模型(LLM)的本地部署过程。它允许用户在自己的硬件上运行和测试最新的语言模型,无需依赖云服务。Ollama提供了一个类似于OpenAI的API接口,使得开发者可以轻松地在自己的应用程序中集成大型语言模型。此外,Ollama WebUI为用户提供了一个友好的界面,用于管理和与模型进行交互。

xiaoli8748的专栏 2332

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: 自动化工具 mitmproxy + python 实现游戏协议测试
下一篇: 进程管理工具 supervisor 简介及使用技巧
星河绛橘色的日落
博客等级 码龄4年 29粉丝 225原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值