接口自动化测试设计思路--设计实战
课程:B站大学
记录python学习,直到学会基本的爬虫,使用python搭建接口自动化测试就算学会了,在进阶webui自动化,app自动化
接口自动化测试设计思路
- 如何进行接口自动化测试设计思路?
- 1. 背景
- 2. 设计目标
- 3. 框架设计
- 3.1 基类设计
- 3.2 工具类设计
- 4. 测试用例实现
- 5. 测试数据管理
- 6. 优势分析
- 7. 总结
- 目前写调用测试用例的流程:
- 实践是检验真理的唯一标准
如何进行接口自动化测试设计思路?
目前收集到的设计方案思路如下:
基类 + 工具类:解决通用逻辑的复用问题。
参数化测试:适合简单场景的大量数据驱动。
集中管理测试数据:提升测试数据维护效率。
数据驱动框架:复杂场景和大规模用例时使用。
数据库动态生成:需要强耦合数据库或验证复杂业务逻辑时使用。
基于基类和工具类的测试框架设计思路
1. 背景
在接口自动化测试中,为了提高代码的复用性、可维护性和扩展性,通常需要设计一个高效的测试框架。本文提出了一种基于基类 + 工具类的设计方案,旨在解决以下问题:
- 测试用例中重复逻辑过多,代码冗余。
- 测试数据难以管理,维护成本高。
- 接口测试的校验逻辑分散,不易复用。
2. 设计目标
- 复用性:
- 通用功能集中封装,避免重复代码。
- 测试数据与测试逻辑分离,提高数据复用率。
- 可维护性:
- 测试代码结构清晰,便于维护和扩展。
- 测试日志与错误信息明确,易于定位问题。
- 扩展性:
- 能快速适配新增的测试场景。
- 支持复杂业务逻辑的验证需求。
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. 优势分析
- 代码复用性:
- 通用功能封装到基类和工具类中,减少重复代码。
- 可维护性:
- 测试数据集中存储,便于管理和更新。
- 测试逻辑清晰,便于团队协作。
- 扩展性:
- 基类和工具类支持新增功能的快速扩展。
- 新增测试场景时,仅需编写少量代码。
小技巧:这里我们可以对每个测试用例的逻辑进行封装,解决在实际业务场景中需要不断的调用不同的接口完成测试,也可以对每个函数打标记@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
适合快速实现接口间依赖的场景方式如下:
独立封装接口函数,手动传递依赖数据:
- 每个接口独立封装为函数
- 通过函数调用传递数据