Pytest Type Safety
Quick Start
Add type annotations to every test function and fixture:
from __future__ import annotations
from typing import Any, AsyncGenerator
from unittest.mock import AsyncMock
import pytest
# ✅ Type annotations on fixture
@pytest.fixture
def create_test_order() -> Any:
def _create(order_id: str = "123") -> Order:
return Order(...)
return _create
# ✅ Type annotations on test
@pytest.mark.asyncio
async def test_extract_orders(
create_test_order: Any,
mock_gateway: AsyncMock,
) -> None:
"""Test function with full type safety."""
use_case = ExtractOrdersUseCase(gateway=mock_gateway)
result = await use_case.execute()
assert result is not None
When to Use
- Write type-safe tests
- Configure mypy for test files
- Use protocols for mocks
- Enforce type checking in CI/CD
- Debug type-related test issues
Key Patterns
Test Functions
def test_product_title() -> None:
"""Test product title creation."""
title: ProductTitle = ProductTitle("Laptop")
assert title.value == "Laptop"
Fixtures
@pytest.fixture
def create_test_line_item() -> Callable[..., LineItem]:
"""Factory for creating line items."""
def _create(
product_id: str = "prod_1",
title: str = "Test Product",
quantity: int = 1,
) -> LineItem:
return LineItem(...)
return _create
Create_Autospec for Type-Safe Mocks
from unittest.mock import create_autospec
# ✅ Mock with autospec enforces interface
def test_with_autospec() -> None:
mock = create_autospec(ShopifyPort, instance=True)
mock.fetch_orders.return_value = []
# mock.typo_method() raises AttributeError
Mypy Configuration
# pyproject.toml
[tool.mypy]
python_version = "3.11"
strict = true
disallow_untyped_defs = true
[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = true
disallow_any_unimported = false # Allow Any from fixtures
Type-Safe Assertions
def test_order_type_safe(create_test_order: Any) -> None:
order: Order = create_test_order()
assert isinstance(order, Order)
assert isinstance(order.customer_name, str)
Supporting Files
| File | Purpose |
|---|---|
| references/type-safety-patterns.md | Complete patterns and CI/CD integration |
Requirements
- Python 3.11+
- pytest >= 7.0
- mypy >= 1.7.0
- pyright >= 1.1.0 (optional)
See Also
- pytest-configuration - mypy config
- pytest-mocking-strategy - create_autospec