mcpField
P
python-testing

python-testing

github.com/laurigates测试与质量59435 次安装今天更新
代码仓库

关于 python-testing

面向 Python 开发者的 pytest 入门与日常测试参考,涵盖测试编写、覆盖率、fixture、参数化和 mock。适用于单模块 TDD 及基础异步测试。

主要功能

  1. 01pytest 基础运行与筛选
  2. 02fixture 和参数化测试
  3. 03覆盖率报告
  4. 04使用 unittest.mock
  5. 05异步测试与 TDD 流程

适用场景

  1. 01为模块编写单元测试
  2. 02用 fixture 准备测试数据
  3. 03检查测试覆盖率
  4. 04模拟外部依赖并测试异步代码

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/laurigates/claude-plugins --skill python-testing

安装后在 Claude Code 中输入/python-testing确认已加载。

附带文件REFERENCE.md

详细介绍

Python 测试

使用 pytest、覆盖率、fixture 和最佳实践进行 Python 测试的快速参考。

何时使用此技能

在以下情况下使用此技能……在以下情况下改用 pytest-advanced……
编写第一个 pytest 测试,学习 fixture 和参数化基础知识设计可复用的 conftest.py fixture 层级或并行执行标记
设置覆盖率报告并使用 unittest.mock 进行基础模拟调整 pytest-xdist、自定义标记或 hookimpl 插件
在单个模块上遵循 TDD 的红-绿-重构循环为多包测试套件构建共享 fixture 库

此技能的适用场景

  • 编写单元测试和集成测试
  • 测试驱动开发(TDD)
  • 测试 fixture 和参数化
  • 覆盖率分析
  • 模拟和打补丁
  • 异步测试

快速参考

运行测试
# Basic test run
uv run pytest

# Verbose output
uv run pytest -v

# Show print statements
uv run pytest -s

# Stop at first failure
uv run pytest -x

# Run specific test
uv run pytest tests/test_module.py::test_function

# Run by keyword
uv run pytest -k "test_user"
测试覆盖率
# Run with coverage
uv run pytest --cov

# HTML report
uv run pytest --cov --cov-report=html

# Show missing lines
uv run pytest --cov --cov-report=term-missing

# Coverage for specific module
uv run pytest --cov=mymodule tests/
Fixture
import pytest

@pytest.fixture
def sample_data():
    return {"key": "value"}

@pytest.fixture(scope="module")
def db_connection():
    conn = create_connection()
    yield conn
    conn.close()

def test_with_fixture(sample_data):
    assert sample_data["key"] == "value"
参数化测试
import pytest

@pytest.mark.parametrize("input,expected", [
    ("hello", "HELLO"),
    ("world", "WORLD"),
    ("test", "TEST"),
])
def test_uppercase(input: str, expected: str):
    assert input.upper() == expected

@pytest.mark.parametrize("value,is_valid", [
    (1, True),
    (0, False),
    (-1, False),
])
def test_validation(value, is_valid):
    assert validate(value) == is_valid
标记
import pytest

@pytest.mark.slow
def test_slow_operation():
    # Long-running test
    pass

@pytest.mark.skip(reason="Not implemented yet")
def test_future_feature():
    pass

@pytest.mark.skipif(sys.platform == "win32", reason="Unix only")
def test_unix_specific():
    pass

@pytest.mark.xfail
def test_known_issue():
    # Expected to fail
    pass
# Run only marked tests
uv run pytest -m slow
uv run pytest -m "not slow"
异步测试
import pytest

@pytest.mark.asyncio
async def test_async_function():
    result = await async_operation()
    assert result == expected_value

@pytest.fixture
async def async_client():
    client = AsyncClient()
    await client.connect()
    yield client
    await client.disconnect()
模拟
from unittest.mock import Mock, patch, MagicMock

def test_with_mock():
    mock_obj = Mock()
    mock_obj.method.return_value = "mocked"
    assert mock_obj.method() == "mocked"

@patch('module.external_api')
def test_with_patch(mock_api):
    mock_api.return_value = {"status": "success"}
    result = call_external_api()
    assert result["status"] == "success"

# pytest-mock (cleaner)
def test_with_mocker(mocker):
    mock = mocker.patch('module.function')
    mock.return_value = 42
    assert function() == 42

测试组织

project/
├── src/
│   └── myproject/
│       ├── __init__.py
│       └── module.py
└── tests/
    ├── __init__.py
    ├── conftest.py          # Shared fixtures
    ├── test_module.py
    └── integration/
        └── test_api.py

conftest.py

# tests/conftest.py
import pytest

@pytest.fixture(scope="session")
def app_config():
    return {"debug": True, "testing": True}

@pytest.fixture(autouse=True)
def reset_db():
    setup_database()
    yield
    teardown_database()

pyproject.toml 配置

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
    "-v",
    "--strict-markers",
    "--cov=src",
    "--cov-report=term-missing",
]
markers = [
    "slow: marks tests as slow",
    "integration: marks tests as integration tests",
]

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

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "def __repr__",
    "raise AssertionError",
    "raise NotImplementedError",
    "if __name__ == .__main__.:",
]

常见测试模式

测试异常
import pytest

def test_raises_exception():
    with pytest.raises(ValueError):
        function_that_raises()

def test_raises_with_message():
    with pytest.raises(ValueError, match="Invalid input"):
        function_that_raises()
测试警告
import pytest

def test_deprecation_warning():
    with pytest.warns(DeprecationWarning):
        deprecated_function()
临时文件
def test_with_tmp_path(tmp_path):
    file_path = tmp_path / "test.txt"
    file_path.write_text("content")
    assert file_path.read_text() == "content"

TDD 工作流

# 1. RED: Write failing test
uv run pytest tests/test_new_feature.py
# FAILED

# 2. GREEN: Implement minimal code
uv run pytest tests/test_new_feature.py
# PASSED

# 3. REFACTOR: Improve code
uv run pytest  # All tests pass

另请参阅

  • uv-project-management - 在项目中添加 pytest
  • python-code-quality - 将测试与 linting 结合
  • python-development - Python 核心开发模式

参考资料

评论

支持 Markdown