当前位置: 首页 > news >正文

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

目的

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

代码步骤设计

第一步:前端调用后端已经写好的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传递参数测试效果

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

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

相关文章:

  • 深入理解 fnmatch 函数的实现
  • 04 redis数据类型
  • 《DeepSeek赋能工业互联网:解锁数据深度分析新姿势》
  • python常用库整理
  • 【实用技巧】云服务器+FRP搭建自己的远程控制向日葵
  • 最简单的难题——游戏英雄升级潜力评估
  • Flutter 跳转后不允许返回
  • 习题系列——数值分析与数值计算
  • el-table树状表格,默认展开第一个节点的每一层
  • 基因研究的“北极盲区”
  • 浏览器开发者工具(F12)查看请求的响应体内容显示”无法加载响应数据: No resource with given identifier found“
  • Linux网络 | 多路转接Reactor
  • HTB—OnlyHacks
  • 利用大模型deepseek搭建本地知识库并且实现 java 调用
  • DRF框架中viewsets.ModelViewSet、APIView区别与联系
  • 八大元素定位
  • TRELLIS 部署笔记
  • 高速硬件电路设计
  • 基于阿里云调用deepseek大模型
  • 如何搭建同城O2O服务平台?AI外卖跑腿APP技术革新与开发实践
  • 水豚出逃40天至今未归,江苏扬州一动物园发悬赏公告
  • 匈牙利史专家阚思静逝世,享年87岁
  • 韩国执政党总统候选人更换方案被否决,金文洙候选人资格即刻恢复
  • 烈士沈绍藩遗孤、革命家帅孟奇养女舒炜逝世,享年96岁
  • 广州下调个人住房公积金贷款利率
  • 西安碑林博物馆票价将调至85元,工作人员:10元属于改扩建期间惠民票