pytest + pytest-mock + pytest-parametrize为基础构建测试框架

一、框架核心组件整合

pytest作为基础测试框架,与pytest-mock(unittest.mock封装)和pytest-parametrize(参数化测试)形成黄金三角。三者协同可实现:

  • 依赖隔离:通过mocker fixture模拟外部API/数据库交互
  • 场景覆盖:利用参数化实现多输入组合测试
  • 代码复用:通过fixture机制实现测试资源共享
二、项目结构设计(推荐方案)
python 复制代码
my_project/
├── src/                  # 业务代码
│   ├── api/              # API模块
│   └── utils/            # 工具函数
├── tests/                # 测试目录
│   ├── unit/             # 单元测试
│   │   ├── test_api.py
│   │   └── test_utils.py
│   ├── integration/      # 集成测试
│   ├── conftest.py       # 全局fixture定义
│   └── pytest.ini        # 配置文件
└── requirements.txt      # 依赖管理
三、核心功能实现示例

1. 参数化测试(pytest-parametrize)

python 复制代码
import pytest

# 基础参数化
@pytest.mark.parametrize("a,b,expected", [
    (2, 3, 5),          # 正常场景
    (0, 0, 0),          # 边界值
    (-1, 1, 0),         # 异常输入
])
def test_add(a, b, expected):
    assert a + b == expected

# 高级用法:结合fixture实现动态参数
@pytest.fixture(params=[
    {"input": "valid", "expected": True},
    {"input": "invalid", "expected": False}
])
def dynamic_data(request):
    return request.param

def test_validation(dynamic_data):
    assert validate(dynamic_data["input"]) == dynamic_data["expected"]

2. Mock服务集成(pytest-mock

python 复制代码
def test_api_call(mocker):
    # 模拟requests.get方法
    mock_get = mocker.patch("requests.get")
    mock_get.return_value.json.return_value = {"status": "ok"}
    
    # 执行测试
    result = fetch_data("https://api.example.com")
    
    # 验证调用
    mock_get.assert_called_once_with("https://api.example.com")
    assert result["status"] == "ok"

3. 复杂场景测试(三者结合)

python 复制代码
@pytest.mark.parametrize("scenario", [
    {"url": "/v1/users", "expected_code": 200},
    {"url": "/v2/users", "expected_code": 404},
])
def test_api_versioning(scenario, mocker):
    # 模拟API响应
    mock_response = mocker.Mock()
    mock_response.status_code = scenario["expected_code"]
    mocker.patch("requests.get", return_value=mock_response)
    
    # 执行测试
    response = call_api(scenario["url"])
    
    # 断言结果
    assert response.status_code == scenario["expected_code"]
四、最佳实践建议
  1. fixture管理:

    • 使用conftest.py定义跨模块fixture
    • 合理设置作用域(function/module/session)
    • 实现fixture依赖链(如db_conn → api_client)
  2. 测试分类:

    • 单元测试:使用mock隔离外部依赖
    • 集成测试:通过--integration标记单独执行
    • 性能测试:添加@pytest.mark.slow标记
  3. 报告与集成:

    • 生成HTML报告:pytest --html=report.html
    • CI集成:配置pytest.ini实现零配置执行
    • 覆盖率分析:结合pytest-cov生成覆盖率报告
五、常用命令参考
python 复制代码
# 运行所有测试
pytest

# 运行指定测试
pytest tests/unit/test_api.py::test_create_user

# 仅运行标记测试
pytest -m "smoke and not slow"

# 生成详细报告
pytest --cov=src --cov-report=html

这套框架设计遵循了测试金字塔原则,既保证了单元测试的执行效率,又通过集成测试验证了模块间协作。通过参数化和mock的结合使用,可在最少代码量下实现最大测试覆盖率。

相关推荐
鬼手点金1 天前
带工具调用的多轮交互:Agent 的核心循环
服务器·人工智能·windows·深度学习·microsoft·机器学习·交互
Madison-No71 天前
pytest框架
pytest
Navicat中国2 天前
Navicat 18 支持 Azure OpenAI 接入,合规 AI 赋能 SQL 开发
数据库·人工智能·microsoft·ai·azure·navicat·数据
张张123y2 天前
2026 Agent 框架怎么选?拆 3 层底层逻辑(运行循环 / 记忆 / 工具协议)+ 一张决策表
linux·ubuntu·microsoft·langgraph·mcp·crewai·agent 框架
霍格沃兹测试学院-小舟畅学2 天前
Playwright CLI:语义快照与局部检索,AI 如何找到正确的页面元素?
人工智能·microsoft
某不知名網友3 天前
ROS2进阶:服务通信、自定义SRV接口、参数服务器与基于服务的参数通信详解
java·开发语言·microsoft
不爱学英文的码字机器3 天前
从Q1迁到T1,同一个编号已经换了含义
前端·数据库·microsoft
龙亘川3 天前
城市公共安全治理如何从“人海战术“走向“数据驱动“?
大数据·数据库·人工智能·安全·microsoft·智慧城市·数据可视化
2503_931712483 天前
数据服务公司怎么帮助企业更高效找到行业数据与商业情报
大数据·人工智能·microsoft
多看书少吃饭4 天前
使用 Qwen 实现实时语音、视频聊天与屏幕共享:原理、接入流程与工程实践
microsoft·音视频