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

接口自动化测试设计思路--设计实战

课程:B站大学
记录python学习,直到学会基本的爬虫,使用python搭建接口自动化测试就算学会了,在进阶webui自动化,app自动化

接口自动化测试设计思路

    • 如何进行接口自动化测试设计思路?
    • 1. 背景
    • 2. 设计目标
    • 3. 框架设计
      • 3.1 基类设计
      • 3.2 工具类设计
      • 4. 测试用例实现
      • 5. 测试数据管理
      • 6. 优势分析
      • 7. 总结
      • 目前写调用测试用例的流程:
  • 实践是检验真理的唯一标准


如何进行接口自动化测试设计思路?

目前收集到的设计方案思路如下:
基类 + 工具类:解决通用逻辑的复用问题。
参数化测试:适合简单场景的大量数据驱动。
集中管理测试数据:提升测试数据维护效率。
数据驱动框架:复杂场景和大规模用例时使用。
数据库动态生成:需要强耦合数据库或验证复杂业务逻辑时使用。
基于基类和工具类的测试框架设计思路

1. 背景

在接口自动化测试中,为了提高代码的复用性、可维护性和扩展性,通常需要设计一个高效的测试框架。本文提出了一种基于基类 + 工具类的设计方案,旨在解决以下问题:

  • 测试用例中重复逻辑过多,代码冗余。
  • 测试数据难以管理,维护成本高。
  • 接口测试的校验逻辑分散,不易复用。

2. 设计目标

  1. 复用性:
  • 通用功能集中封装,避免重复代码。
  • 测试数据与测试逻辑分离,提高数据复用率。
  1. 可维护性:
  • 测试代码结构清晰,便于维护和扩展。
  • 测试日志与错误信息明确,易于定位问题。
  1. 扩展性:
  • 能快速适配新增的测试场景。
  • 支持复杂业务逻辑的验证需求。

3. 框架设计

3.1 基类设计

核心功能:

  • 提供测试前后的通用操作(如环境初始化)。
  • 提供常用的辅助方法(如加载测试数据、通用校验等)。
  • 测试用例类通过继承基类复用其功能。
    示例代码
import pytest
import json
class BaseTest:@pytest.fixture(scope="class", autouse=True)def setup(self):"""测试初始化,执行每个测试类前的准备工作"""self.api = APIClient()  # 初始化 API 客户端实例def load_test_data(self, file_path):"""从指定文件加载 JSON 测试数据"""try:with open(file_path, 'r', encoding='utf-8') as file:return json.load(file)except FileNotFoundError:raise FileNotFoundError(f"Test data file not found: {file_path}")except json.JSONDecodeError:raise ValueError(f"Invalid JSON format in file: {file_path}")def validate_response(self, response, expected_data):"""验证接口响应字段是否匹配"""for key, value in expected_data.items():assert response.data[key] == value, f"Mismatch for {key}: expected {value}, got {response.data[key]}"

3.2 工具类设计

核心功能:

  • 封装通用工具方法(如数据校验、日志记录)。
  • 提供独立于测试逻辑的功能支持,供多个模块调用。
    示例代码
class TestUtils:@staticmethoddef compare_dicts(expected, actual):"""比较两个字典的值"""for key, value in expected.items():assert actual[key] == value, f"Key '{key}' mismatch: expected {value}, got {actual}"@staticmethoddef log_request_response(request, response):"""记录请求和响应日志"""print(f"Request: {request}")print(f"Response: {response}")@staticmethoddef generate_unique_id():"""生成唯一标识符(示例方法)"""import uuidreturn str(uuid.uuid4())

4. 测试用例实现

核心思路:

  • 测试用例类继承 BaseTest,复用初始化和通用方法。
  • 根据具体场景调用工具类中的方法,简化测试逻辑。
    示例代码
import pytest
from test_utils import TestUtils
class TestCategory(BaseTest):@pytest.fixture(scope="class", autouse=True)def setup(self):"""继承基类 setup 并扩展初始化逻辑"""super().setup()self.create_data_file = "create_data.json"self.update_data_file = "update_data.json"def test_create_category(self):"""测试新增商品分类"""data = self.load_test_data(self.create_data_file)  # 加载测试数据response = self.api.createCategory(data)          # 调用接口assert response.code == 0                         # 验证接口响应assert response.data is not None                  # 验证是否返回数据def test_update_category(self):"""测试修改商品分类"""data = self.load_test_data(self.update_data_file)  # 加载测试数据response = self.api.updateCategory(data)          # 调用接口assert response.code == 0                         # 验证接口响应assert response.data is True                      # 验证是否返回正确结果def test_validate_category(self):"""验证修改后的分类是否正确"""expected_data = self.load_test_data(self.update_data_file)category_id = expected_data["categoryId"]response = self.api.getCategory(category_id)assert response.code == 0self.validate_response(response, expected_data)   # 使用基类方法验证字段

5. 测试数据管理

  • 集中化管理:
    • 将测试数据保存在 JSON 文件中,按模块或场景划分。
    • 文件命名建议:create_data.json、update_data.json。
  • 动态加载:
    • 使用基类中的方法动态加载测试数据,减少硬编码。
      示例测试数据
create_data.json
{"categoryId": 1,"shopId": 1,"categoryName": "创建商品分类","memberDiscountInfo": [],"isShopDisplay": 1,"isDeleted": 0,"sort": 1,"createBy": "tester","createTime": "2023-10-01T00:00:00","updateBy": "tester","updateTime": "2023-10-01T00:00:00"
}

6. 优势分析

  1. 代码复用性:
  • 通用功能封装到基类和工具类中,减少重复代码。
  1. 可维护性:
  • 测试数据集中存储,便于管理和更新。
  • 测试逻辑清晰,便于团队协作。
  1. 扩展性:
  • 基类和工具类支持新增功能的快速扩展。
  • 新增测试场景时,仅需编写少量代码。

小技巧:这里我们可以对每个测试用例的逻辑进行封装,解决在实际业务场景中需要不断的调用不同的接口完成测试,也可以对每个函数打标记@pytest.mark.update_category(目前没感觉到用处)
比如:存在一个写了对于模块所有调用接口的测试用例文件test_case_helpers.py,新建一个test_category.py文件用来模拟实际的业务场景。但是也有个问题,如果一个场景就是一个py文件,岂不是需要新建很多的py文件??(貌似可以一个py文件中定义不同的类,不同的类对应不同的业务场景,py文件看上去少)
示例:

# test_product.py
import pytest
from test_case_helpers import test_create_product, test_update_product, test_get_productclass TestCreateProduct:def test_create_product(self, api_client):"""新增商品的测试"""test_create_product(api_client, "create_product_data.json")def test_validate_create(self, api_client):"""新增商品后验证商品信息"""test_get_product(api_client, "create_product_data.json")class TestUpdateProduct:def test_update_product(self, api_client):"""修改商品的测试"""test_update_product(api_client, "update_product_data.json")def test_validate_update(self, api_client):"""修改商品后验证商品信息"""test_get_product(api_client, "update_product_data.json")class TestCreateAndValidateProduct:def test_create_and_validate(self, api_client):"""新增商品并查看新增是否正确"""test_create_product(api_client, "create_product_data.json")test_get_product(api_client, "create_product_data.json")class TestUpdateAndValidateProduct:def test_update_and_validate(self, api_client):"""修改商品并查看修改是否正确"""test_update_product(api_client, "update_product_data.json")test_get_product(api_client, "update_product_data.json")

7. 总结

1、通过基类与工具类的设计,可以有效提升接口自动化测试的开发效率与代码质量。
2、就目前而言,我发现可以用下面的方式写:
1.1:通过单独的casehelp.py文件封装该模块下能调用的所有接口方法为不同的def函数(每个函数里面进行具体的断言以及覆盖率等),
1.2:在外部新建一个actl_case.py文件进行直接调用def函数进行测试,使用@pytest.mark.run(order=xxx)执行函数的运行顺序(这里在想可以写个py脚本把casehelp.py文件中的def函数名都读取出来写入到actl_case.py文件中并在每个def函数头一行前加入@pytest.mark.run(order=xxx)装饰器),然后只需要更改order就可以完成不同业务场景的测试了。
1.3:actl.case文件一个业务场景新建一个类,一个类就对应一个业务场景,然后给这个类打上标记@pytest.mark.xxx,运行的时候过滤筛选标记执行。

目前写调用测试用例的流程:

1、新建test_xxx_xxx测试用例文件
2、查看api指定的请求数据模型,生成对应的json测试数据
3、区分不同的请求接口:
POST:有json的创建json测试数据、有dict的传字典、params的用例参数化
GET:参数少的用例参数化,参数多的用json
适合快速实现接口间依赖的场景方式如下:
独立封装接口函数,手动传递依赖数据:

  1. 每个接口独立封装为函数
  2. 通过函数调用传递数据
    在这里插入图片描述

实践是检验真理的唯一标准

相关文章:

  • 【信息安全相关基础篇:了解签名与验签是什么及用途】
  • 蓝桥杯13届 卡牌
  • Dapp开发-如何开发一个dapp
  • Transformer——Q74 推导动态FFN(Dynamic FFN)的门控权重更新公式
  • 【内蒙古】《内蒙古自治区本级政务信息化建设项目预算支出标准(试行)》(内财预〔2024〕1449号)-费用标准解读系列
  • 计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 09.天空和背景
  • 交叉类型的属性合并规则
  • 数组作为指针计算大小时的误区
  • 扩展:React 项目执行 yarn eject 后的 config 目录结构详解
  • Kotlin 内联函数(Inline Functions):性能优化与实战指南
  • CSS3 遮罩
  • 嵌入式Linux I2C驱动开发详解
  • 架构、构架、结构、框架之间有什么区别?|系统设计|系统建模
  • Golang 应用的 CI/CD 与 K8S 自动化部署全流程指南
  • TCPIP详解 卷1协议 九 广播和本地组播(IGMP 和 MLD)
  • geoserver发布arcgis瓦片地图服务(最新版本)
  • cursor 出现 unauthorized request
  • 编译原理AST以Babel为例进行解读、Webpack中自定义loader与plugin
  • 主流编程语言中ORM工具全解析
  • 区块链钱包开发全解析:从架构设计到安全生态构建
  • 印度证实印巴已同意停火
  • 重温经典|开播20周年,仙剑的那些幕后你知道吗?
  • 印巴战火LIVE丨“快速接近战争状态”?印度袭击巴军事基地,巴启动反制军事行动
  • 欧盟公布对美关税反制清单,瞄准美国飞机等产品
  • 越秀地产前4个月销售额约411.2亿元,达年度销售目标的34.1%
  • 对话哭泣照被恶意盗用成“高潮针”配图女生:难过又屈辱