pytest 测试项目指南

下面是一个完整的 pytest 测试项目结构示例,包含了最佳实践和常见配置:

项目结构

Plain Text

复制代码
project-name/
├── src/                     # 应用程序源代码
│   └── app.py
├── tests/                   # 测试目录
│   ├── unit/                # 单元测试
│   │   ├── test_app.py
│   │   └── test_utils.py
│   ├── integration/         # 集成测试
│   │   └── test_api.py
│   ├── conftest.py          # 共享的fixture和配置
│   └── pytest.ini           # pytest配置文件
├── .gitignore
├── requirements.txt         # 项目依赖
└── setup.py                 # 安装脚本(可选)

关键文件内容

1. src/app.py (示例应用代码)

python

复制代码
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def multiply(a, b):
    return a * b

def divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

2. tests/unit/test_app.py (单元测试)

python

复制代码
import pytest
from src.app import add, subtract, multiply, divide

class TestMathOperations:
    def test_add(self):
        assert add(2, 3) == 5
        assert add(-1, 1) == 0
        
    def test_subtract(self):
        assert subtract(5, 3) == 2
        assert subtract(3, 5) == -2
        
    def test_multiply(self):
        assert multiply(3, 4) == 12
        assert multiply(0, 5) == 0
        
    def test_divide(self):
        assert divide(10, 2) == 5
        
    def test_divide_by_zero(self):
        with pytest.raises(ValueError) as exc_info:
            divide(10, 0)
        assert "Cannot divide by zero" in str(exc_info.value)

3. tests/conftest.py (共享fixture)

python

复制代码
import pytest

# 共享fixture示例
@pytest.fixture
def sample_data():
    return {"a": 10, "b": 5}

# 配置pytest钩子
def pytest_addoption(parser):
    parser.addoption("--slow", action="store_true", default=False, 
                     help="Run slow tests")

def pytest_collection_modifyitems(config, items):
    if not config.getoption("--slow"):
        skip_slow = pytest.mark.skip(reason="need --slow option to run")
        for item in items:
            if "slow" in item.keywords:
                item.add_marker(skip_slow)

4. tests/pytest.ini (配置文件)

ini

复制代码
[pytest]
addopts = -v --cov=src --cov-report=html
testpaths = tests/unit tests/integration
markers =
    slow: marks tests as slow (deselect with '-m "not slow"')

5. requirements.txt (依赖文件)

Plain Text

复制代码
pytest==7.1.2
pytest-cov==3.0.0
requests==2.27.1  # 用于API测试

运行测试

基本命令

bash

复制代码
# 运行所有测试
pytest

# 运行特定目录下的测试
pytest tests/unit

# 运行特定文件中的测试
pytest tests/unit/test_app.py

# 运行特定类中的测试
pytest tests/unit/test_app.py::TestMathOperations

# 运行特定测试方法
pytest tests/unit/test_app.py::TestMathOperations::test_add

高级选项

bash

复制代码
# 生成覆盖率报告
pytest --cov=src

# 只运行标记为slow的测试
pytest -m slow

# 跳过标记为slow的测试
pytest -m "not slow"

# 在失败时启动调试器
pytest --pdb

# 并行运行测试(需要pytest-xdist)
pytest -n auto

最佳实践

  1. 命名约定

    • 测试文件:test_*.py*_test.py

    • 测试类:Test*

    • 测试方法:test_*

  2. 测试组织

    • 按功能模块分组测试

    • 将单元测试与集成测试分离

    • 使用标记(markers)分类测试

  3. 使用fixture

    • 避免重复设置代码

    • 创建可重用的测试环境

    • 使用conftest.py共享fixture

  4. 参数化测试

    python

    复制代码
    @pytest.mark.parametrize("a,b,expected", [
        (1, 2, 3),
        (-1, 1, 0),
        (10, 20, 30)
    ])
    def test_add(a, b, expected):
        assert add(a, b) == expected
  5. 测试覆盖率

    • 使用pytest-cov生成覆盖率报告

    • 目标覆盖关键业务逻辑

    • 但不要追求100%覆盖率(可能产生低价值测试)

  6. 持续集成

    • 在CI/CD流程中运行测试

    • 设置测试失败时的警报

    • 使用测试结果作为质量门禁

常见插件

  1. pytest-cov:代码覆盖率报告

  2. pytest-xdist:并行运行测试

  3. pytest-mock:简化mock使用

  4. pytest-django:Django项目支持

  5. pytest-asyncio:异步测试支持

  6. pytest-html:生成HTML报告

调试技巧

  1. 使用pytest --trace在测试开始时启动调试器

  2. 添加print()语句输出调试信息

  3. 使用pytest -s禁用输出捕获(显示print输出)

  4. 在失败测试中使用pdb

    python

    复制代码
    def test_failing():
        result = some_function()
        import pdb; pdb.set_trace()  # 在此设置断点
        assert result == expected

这个结构提供了一个健壮的测试基础,可以根据项目需求进行调整和扩展。

相关推荐
不吃香菜学java2 天前
苍穹外卖-菜品分页查询
数据库·spring boot·tomcat·log4j·maven·mybatis
不吃香菜学java2 天前
苍穹外卖-新增菜品代码开发
spring boot·spring·servlet·log4j·maven·mybatis
sxhcwgcy2 天前
Spring Boot 整合 log4j2 日志配置教程
spring boot·单元测试·log4j
dreamxian3 天前
苍穹外卖day09
java·spring boot·tomcat·log4j·maven
大黄说说5 天前
测试金字塔的实战演进:单元测试、集成测试与系统测试的深度解析与高效落地
log4j
Code_LT5 天前
【AIGC】Claude Code 模型配置详解
log4j·aigc
Welcome_Back5 天前
SpringBoot后端开发测试全指南
spring boot·后端·log4j
kkkkkkkkl246 天前
Prompt 不只是提问:大模型的“输入程序”机制解析
log4j
de_wizard7 天前
Spring Boot 项目开发流程全解析
java·spring boot·log4j