pytest精通Skill pytest-mastery

pytest 精通技能专注于使用 Python 的 pytest 框架和 uv 包管理器进行高效、全面的软件测试。它涵盖了从编写、运行、参数化测试到生成覆盖率报告的全流程,特别适用于单元测试、集成测试以及 FastAPI 等现代 Web 应用的测试。核心关键词包括:Python 测试、pytest、单元测试、集成测试、测试覆盖率、FastAPI 测试、测试夹具、参数化测试、测试调试、uv 包管理器。

测试 0 次安装 1 次浏览 更新于 3/1/2026

name: pytest-mastery description: | 使用 uv 包管理器进行 Python 测试。适用于:(1) 运行 Python 测试,(2) 编写测试文件或测试函数,(3) 设置测试夹具,(4) 参数化测试,(5) 生成覆盖率报告,(6) 测试 FastAPI 应用,(7) 调试测试失败,(8) 配置 pytest 选项。触发词:“运行测试”、“编写测试”、“测试覆盖率”、“pytest”、“单元测试”、“集成测试”、“测试 FastAPI”。

使用 uv 进行 pytest 测试

快速参考

# 运行所有测试
uv run pytest

# 运行并输出详细信息
uv run pytest -v

# 运行特定文件
uv run pytest tests/test_example.py

# 运行特定测试函数
uv run pytest tests/test_example.py::test_function_name

# 运行匹配模式的测试
uv run pytest -k "pattern"

# 运行测试并生成覆盖率报告
uv run pytest --cov=src --cov-report=html

安装

# 将 pytest 添加为开发依赖
uv add --dev pytest

# 添加覆盖率支持
uv add --dev pytest-cov

# 添加异步支持(用于 FastAPI)
uv add --dev pytest-asyncio httpx

测试发现

pytest 自动发现遵循以下约定的测试:

  • 文件:test_*.py*_test.py
  • 函数:test_*
  • 类:Test*(无 __init__ 方法)
  • 方法:Test* 类内的 test_*

标准项目结构:

project/
├── src/
│   └── myapp/
├── tests/
│   ├── __init__.py
│   ├── conftest.py      # 共享夹具
│   ├── test_unit.py
│   └── integration/
│       └── test_api.py
└── pyproject.toml

夹具

夹具提供可重用的测试设置/拆卸:

import pytest

@pytest.fixture
def sample_user():
    return {"id": 1, "name": "测试用户"}

@pytest.fixture
def db_connection():
    conn = create_connection()
    yield conn  # 测试在此处运行
    conn.close()  # 拆卸

def test_user_name(sample_user):
    assert sample_user["name"] == "测试用户"

夹具作用域

@pytest.fixture(scope="function")  # 默认:每个测试新实例
@pytest.fixture(scope="class")     # 每个测试类一次
@pytest.fixture(scope="module")    # 每个模块一次
@pytest.fixture(scope="session")   # 每个测试会话一次

共享夹具 (conftest.py)

放置在 tests/conftest.py 中以便自动可用:

# tests/conftest.py
import pytest

@pytest.fixture
def api_client():
    return TestClient(app)

参数化

使用多个输入运行相同的测试:

import pytest

@pytest.mark.parametrize("input,expected", [
    (1, 2),
    (2, 4),
    (3, 6),
])
def test_double(input, expected):
    assert input * 2 == expected

@pytest.mark.parametrize("value", [None, "", [], {}])
def test_falsy_values(value):
    assert not value

常用选项

选项 描述
-v 详细输出
-vv 更详细输出
-q 静默模式
-x 首次失败时停止
--lf 仅运行上次失败的测试
--ff 先运行失败的测试
-k "expr" 按名称表达式过滤
-m "mark" 仅运行标记的测试
--tb=short 较短的回溯
--tb=no 无回溯
-s 显示打印语句
--durations=10 显示 10 个最慢的测试
-n auto 并行执行 (pytest-xdist)

覆盖率报告

# 终端报告
uv run pytest --cov=src

# HTML 报告(创建 htmlcov/ 目录)
uv run pytest --cov=src --cov-report=html

# 设置最低阈值(低于阈值则失败)
uv run pytest --cov=src --cov-fail-under=80

# 多种报告格式
uv run pytest --cov=src --cov-report=term --cov-report=xml

标记器

import pytest

@pytest.mark.slow
def test_slow_operation():
    ...

@pytest.mark.skip(reason="未实现")
def test_future_feature():
    ...

@pytest.mark.skipif(condition, reason="...")
def test_conditional():
    ...

@pytest.mark.xfail(reason="已知错误")
def test_known_failure():
    ...

按标记运行:

uv run pytest -m "not slow"
uv run pytest -m "integration"

pyproject.toml 配置

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = "-v --tb=short"
markers = [
    "slow: 将测试标记为慢速",
    "integration: 集成测试",
]

[tool.coverage.run]
source = ["src"]
omit = ["tests/*", "*/__init__.py"]

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "if TYPE_CHECKING:",
]

FastAPI 测试

有关全面的 FastAPI 测试模式,请参阅 references/fastapi-testing.md,包括:

  • TestClient 设置
  • 使用 httpx 进行异步测试
  • 数据库夹具模式
  • 依赖项覆盖
  • 身份验证测试

调试失败的测试

# 运行并显示完整回溯
uv run pytest --tb=long

# 失败时进入调试器
uv run pytest --pdb

# 在回溯中显示局部变量
uv run pytest -l

# 仅运行之前失败的测试
uv run pytest --lf