自动化测试框架搭建-单次接口执行-三部曲

news2025/2/22 10:54:16

目的

判断接口返回值和提前设置的预期是否一致,从而判断本次测试是否通过

代码步骤设计

第一步:前端调用后端已经写好的POST接口,并传递参数

第二步:后端接收到参数,组装并请求指定接口,保存返回

第三步:预期结果对比接口返回,一致返回测试通过,不一致返回接口本次测试的真实数据

代码实现思路

第一步

1、接口的请求的方式是post
2、前端以post形式提交参数信息
3、接口将单个参数信息读取放到后端代码的变量中

第二步

1、根据解析的后端变量填入接口调用的参数中
2、访问指定接口,保存接口返回的json数据

第三步

1、读取忽略字段,如果没有,对接口返回的json数据(json转化为字典数据类型)做全量校验
2、读取忽略字段,如果有,对接口返回的json数据(json转化为字典数据类型)做校验,遇见匹配的忽略字段跳过
3、返回对比结果

4、对比一致,返回接口测试通过

返回差异数据(为空)

5、对比不一致,接口测试不通过

返回差异数据(不为空)

代码实现

步骤一
1、接收post请求的参数
from flask import request
from flask_restful import Resource

from app.api.common.utils import res
from app.commen.resopDiff import resp_diff
from app.interfaces.interfaces import interfaces


class TestCase(Resource):

    def post(self):
        data = request.get_json()

        if not data:
            # 返回明确的错误信息,避免引用未定义的 result
            # 400 Bad Request
            return res(message="请求数据为空", success=False, code=400)

        try:
            # 打印接收到的数据(调试用)
            # print("Received data:", data)

            # 提取必要字段(建议增加字段存在性校验)
            method = data.get('method')
            url = data.get('url')
            params = data.get('params', {})  # 默认空字典
            headers = data.get('headers', {})  # 默认空字典
            expected = data.get('expected')  # 注意字段名拼写是否正确
            ignore_keys = data.get('ignore_keys', [])

            # 调用接口请求
            resp = interfaces.request(
                method=method,
                url=url,
                headers=headers,
                params=params
            )

            # 确保获取响应文本内容
            resp_text = resp.text


            #  调试输出响应内容
            # print("Response text:", resp_text)

            # 对比预期结果与实际响应
            # 假设 resp_diff 返回可序列化的字典(需确保实现正确)
            result = resp_diff(expected, resp_text, ignore_keys)

            # 构建返回结果
            if not result:  # 等价于 result == {}

                return res(data=result, message="接口对比一致,测试通过!", success=True, code=200)
            else:

                return res(data=result, message="接口对比不一致,测试不通过!", success=True, code=200)

        except KeyError as e:
            # 处理字段缺失错误

            return res(message=f"请求数据缺少必要字段: {str(e)}", success=False, code=500)

        except Exception as e:
            # 捕获其他异常(如接口请求失败)

            return res(message=f"服务器内部错误: {str(e)}", success=False, code=500)
步骤二

2、resp_diff(预期结果与实际响应求差异值)

from deepdiff import DeepDiff
import json


# 参数要求,需要对比的是json字符串,以及需要忽略的字段

def resp_diff(expected, realResp, ignore_keys):
    """
    比较两个 JSON 数据的差异,并忽略指定的键。

    :param expected: 第一个 JSON 数据(字符串或字典)
    :param realResp: 第二个 JSON 数据(字符串或字典)
    :param ignore_keys: 需要忽略的键的列表(例如 ["extra", "age"])
    :return: 返回比较结果的描述和差异(如果有)
    """
    # 如果输入是字符串,将其解析为字典
    if isinstance(expected, str):
        dict1 = json.loads(expected)
    else:
        dict1 = expected

    if isinstance(realResp, str):
        dict2 = json.loads(realResp)
    else:
        dict2 = realResp

    # 构造 exclude_paths 参数
    exclude_paths = {f"root['{key}']" for key in ignore_keys}

    # print(f"ignore_keys{ignore_keys}")
    # # 使用 DeepDiff 进行比对
    # print(f"dict1{dict1}")
    # print(f"dict2{dict2}")
    # print(f"exclude_paths:{exclude_paths}")
    diff = DeepDiff(dict2, dict1, exclude_paths=exclude_paths)

    # 返回比较结果,直接返回diff需要对diff做判断

    return rename_diff_keys(diff)

def rename_diff_keys(diff_dict):
    """
    递归遍历 DeepDiff 结果,将 new_value/old_value 替换为自定义名称
    """
    if not isinstance(diff_dict, dict):
        return diff_dict

    renamed = {}
    for key, value in diff_dict.items():
        # 直接替换字段名
        if key == "new_value":
            renamed["realResp"] = value
        elif key == "old_value":
            renamed["expected"] = value
        # 递归处理嵌套结构
        elif isinstance(value, dict):
            renamed[key] = rename_diff_keys(value)
        elif isinstance(value, list):
            renamed[key] = [rename_diff_keys(item) if isinstance(item, dict) else item for item in value]
        else:
            renamed[key] = value
    return renamed

3、在蓝图上注册接口,访问路径

api.add_resource(TestCase, '/interfaces/post1')

4、通过Postman传递参数测试效果

  • 结果与预期一致
    请添加图片描述

  • 结果与预期不一致
    请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2301080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DeepSeek R1生成图片总结2(虽然本身是不能直接生成图片,但是可以想办法利用别的工具一起实现)

DeepSeek官网 目前阶段,DeepSeek R1是不能直接生成图片的,但可以通过优化文本后转换为SVG或HTML代码,再保存为图片。另外,Janus-Pro是DeepSeek的多模态模型,支持文生图,但需要本地部署或者使用第三方工具。…

ESP32 ESP-IDF TFT-LCD(ST7735 128x160) LVGL基本配置和使用

ESP32 ESP-IDF TFT-LCD(ST7735 128x160) LVGL基本配置和使用 📍项目地址:https://github.com/lvgl/lv_port_esp32参考文章:https://blog.csdn.net/chentuo2000/article/details/126668088https://blog.csdn.net/p1279030826/article/details/…

【笔记】LLM|Ubuntu22服务器极简本地部署DeepSeek+联网使用方式

2025/02/18说明:2月18日~2月20日是2024年度博客之星投票时间,走过路过可以帮忙点点投票吗?我想要前一百的实体证书,经过我严密的计算只要再拿到60票就稳了。一人可能会有多票,Thanks♪(・ω・)&am…

Linux的基础指令和环境部署,项目部署实战(下)

目录 上一篇:Linxu的基础指令和环境部署,项目部署实战(上)-CSDN博客 1. 搭建Java部署环境 1.1 apt apt常用命令 列出所有的软件包 更新软件包数据库 安装软件包 移除软件包 1.2 JDK 1.2.1. 更新 1.2.2. 安装openjdk&am…

数值积分:通过复合梯形法计算

在物理学和工程学中,很多问题都可以通过数值积分来求解,特别是当我们无法得到解析解时。数值积分是通过计算积分区间内离散点的函数值来近似积分的结果。在这篇博客中,我将讨论如何使用 复合梯形法 来进行数值积分,并以一个简单的…

【Java计算机毕业设计】基于SSM+VUE保险公司管理系统数据库源代码+LW文档+开题报告+答辩稿+部署教程+代码讲解

源代码数据库LW文档(1万字以上)开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统:Window操作系统 2、开发工具:IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

C#之上位机开发---------C#通信库及WPF的简单实践

〇、上位机,分层架构 界面层 要实现的功能: 展示数据 获取数据 发送数据 数据层 要实现的功能: 转换数据 打包数据 存取数据 通信层 要实现的功能: 打开连接 关闭连接 读取数据 写入数据 实体类 作用: 封装数据…

仿 Sora 之形,借物理模拟之技绘视频之彩

来自麻省理工学院、斯坦福大学、哥伦比亚大学以及康奈尔大学的研究人员携手开源了一款创新的3D交互视频模型——PhysDreamer(以下简称“PD”)。PD与OpenAI旗下的Sora相似,能够借助物理模拟技术来生成视频,这意味着PD所生成的视频蕴…

RedisTemplate存储含有特殊字符解决

ERROR信息: 案发时间: 2025-02-18 01:01 案发现场: UserServiceImpl.java 嫌疑人: stringRedisTemplate.opsForValue().set(SystemConstants.LOGIN_CODE_PREFIX phone, code, Duration.ofMinutes(3L)); // 3分钟过期作案动机: stringRedisTemplate继承了Redistemplate 使用的…

Django REST Framework (DRF) 中用于构建 API 视图类解析

Django REST Framework (DRF) 提供了丰富的视图类,用于构建 API 视图。这些视图类可以分为以下几类: 1. 基础视图类 这些是 DRF 中最基础的视图类,通常用于实现自定义逻辑。 常用类 APIView: 最基本的视图类,所有其…

Zotero PDF Translate插件配置百度翻译api

Zotero PDF Translate插件可以使用几种翻译api,虽然谷歌最好用,但是由于众所周知的原因,不稳定。而cnki有字数限制,有道有时也不行。其他的翻译需要申请密钥。本文以百度为例,进行申请 官方有申请教程: Zot…

Redis离线安装

Linux系统Centos安装部署Redis缓存插件 参考:Redis中文网: https://www.redis.net.cn/ 参考:RPM软件包下载地址: https://rpmfind.net/linux/RPM/index.html http://rpm.pbone.net/ https://mirrors.aliyun.com/centos/7/os…

五、k8s:容忍 存储卷

容忍: 即使节点上有污点,依然可以部署pod。 tolerations: operator: "Exists" 不指定key,表示容忍所有的污点 cordon和drain cordon: 直接标记节点为不可用,pod不能部署到该节点。新建的pod不会再部署到该节点&#…

零售顶流三只松鼠如何重塑品牌营销新生态,寻找新的增长点?

在零售行业的变革浪潮中,三只松鼠作为休闲零食领域的代表品牌,面临着前所未有的机遇与挑战。在竞争激烈的零售市场中,三只松鼠以其突出的表现成为行业焦点。2024 年前三季度,营收 71.69 亿元,同比增长 56.46%&#xff…

USC 安防平台之移动侦测

随着第四次科技革命的开启,AI技术获取了突飞猛进的发展,视频监控对应的视频分析技术也获取了巨大的发展。 还记得15年前采用人工提取特征做前景背景分离和提取,大部分依赖CPU,最多使用一下TI的DM642 DSP加速,开发难度…

MySQL智障离谱问题,删了库确还存在、也不能再创建同名库

1、问题 今天跟后端朋友接毕设单子的时候,后端穿过来的【weather.sql】这个文件没弄好,导致这个【weather】数据库的数据是错的,因此我用datagrip的GUI界面直接右键删除,结果就是tmd删不掉,ok,我只能在那新…

IIS asp.net权限不足

检查应用程序池的权限 IIS 应用程序池默认使用一个低权限账户(如 IIS_IUSRS),这可能导致无法删除某些文件或目录。可以通过以下方式提升权限: 方法 1:修改应用程序池的标识 打开 IIS 管理器。 在左侧导航树中&#x…

pptx文档提取信息

目录 一、前言二、python-pptx提取核心代码三、LibreOffice 转换pdf再提取的核心代码一、前言 pptx文档提取解析常用的库。 如果只需要解析 .pptx 的文本、表格、图片,推荐使用 python-pptx(开源,轻量级)。 如果需要高性能、支持 .ppt、动画、格式转换,推荐 Aspose.Slid…

嵌入式八股文(四)计算机网络篇

第一章 基础概念 1. 服务 指网络中各层为紧邻的上层提供的功能调用,是垂直的。包括面向连接服务、无连接服务、可靠服务、不可靠服务。 2. 协议 是计算机⽹络相互通信的对等层实体之间交换信息时必须遵守的规则或约定的集合。⽹络协议的三个基本要素:语法、…

用deepseek学大模型04-机器学习建模过程

https://metaso.cn/s/7tEmBHr 目前已经学完深度学习的数学基础,给出机器学习建模的基本过程 好的,我现在需要回答用户的问题:已经学完深度学习的数学基础,现在要给出机器学习建模的基本过程。我需要结合我搜索到的资料来构建一个详…