mcpField
P
pytest

pytest

github.com/gentleman-programming测试与质量661289 次安装31 周前更新
代码仓库

关于 pytest

介绍 pytest 常见模式与命令的 Python 测试技能,面向编写测试的开发者,涵盖 fixture、模拟、参数化、标记和异步测试示例。

主要功能

  1. 01测试结构示例
  2. 02Fixture 与共享 conftest.py 设置
  3. 03使用 unittest.mock 进行模拟
  4. 04参数化测试与标记
  5. 05异步测试示例
  6. 06pytest 命令参考

适用场景

  1. 01创建可复用的测试设置
  2. 02测试调用外部服务的代码
  3. 03运行筛选或带标记的测试
  4. 04编写异步和参数化测试

安装

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

$npx skills add https://github.com/gentleman-programming/gentleman-skills --skill pytest

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

详细介绍

基本测试结构

import pytest

class TestUserService:
    def test_create_user_success(self):
        user = create_user(name="John", email="[email protected]")
        assert user.name == "John"
        assert user.email == "[email protected]"

    def test_create_user_invalid_email_fails(self):
        with pytest.raises(ValueError, match="Invalid email"):
            create_user(name="John", email="invalid")

Fixture

import pytest

@pytest.fixture
def user():
    """Create a test user."""
    return User(name="Test User", email="[email protected]")

@pytest.fixture
def authenticated_client(client, user):
    """Client with authenticated user."""
    client.force_login(user)
    return client

# Fixture with teardown
@pytest.fixture
def temp_file():
    path = Path("/tmp/test_file.txt")
    path.write_text("test content")
    yield path  # Test runs here
    path.unlink()  # Cleanup after test

# Fixture scopes
@pytest.fixture(scope="module")  # Once per module
@pytest.fixture(scope="class")   # Once per class
@pytest.fixture(scope="session") # Once per test session

conftest.py

# tests/conftest.py - Shared fixtures
import pytest

@pytest.fixture
def db_session():
    session = create_session()
    yield session
    session.rollback()

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

模拟

from unittest.mock import patch, MagicMock

class TestPaymentService:
    def test_process_payment_success(self):
        with patch("services.payment.stripe_client") as mock_stripe:
            mock_stripe.charge.return_value = {"id": "ch_123", "status": "succeeded"}

            result = process_payment(amount=100)

            assert result["status"] == "succeeded"
            mock_stripe.charge.assert_called_once_with(amount=100)

    def test_process_payment_failure(self):
        with patch("services.payment.stripe_client") as mock_stripe:
            mock_stripe.charge.side_effect = PaymentError("Card declined")

            with pytest.raises(PaymentError):
                process_payment(amount=100)

# MagicMock for complex objects
def test_with_mock_object():
    mock_user = MagicMock()
    mock_user.id = "user-123"
    mock_user.name = "Test User"
    mock_user.is_active = True

    result = get_user_info(mock_user)
    assert result["name"] == "Test User"

参数化

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

@pytest.mark.parametrize("email,is_valid", [
    ("[email protected]", True),
    ("invalid-email", False),
    ("", False),
    ("[email protected]", False),
])
def test_email_validation(email, is_valid):
    assert validate_email(email) == is_valid

标记

# pytest.ini or pyproject.toml
[tool.pytest.ini_options]
markers = [
    "slow: marks tests as slow",
    "integration: marks integration tests",
]

# Usage
@pytest.mark.slow
def test_large_data_processing():
    ...

@pytest.mark.integration
def test_database_connection():
    ...

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

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

# Run specific markers
# pytest -m "not slow"
# pytest -m "integration"

异步测试

import pytest

@pytest.mark.asyncio
async def test_async_function():
    result = await async_fetch_data()
    assert result is not None

命令

pytest                          # Run all tests
pytest -v                       # Verbose output
pytest -x                       # Stop on first failure
pytest -k "test_user"           # Filter by name
pytest -m "not slow"            # Filter by marker
pytest --cov=src                # With coverage
pytest -n auto                  # Parallel (pytest-xdist)
pytest --tb=short               # Short traceback

关键词

pytest, python, testing, fixtures, mocking, parametrize, markers

评论

支持 Markdown