
pytest-fastapi
Testing FastAPI applications with pytest using Test-Driven Development (TDD). Use when writing tests
提供方 ashfaq1192|开源
Pytest FastAPI Testing
Write and run tests for FastAPI applications using pytest, TestClient, and async testing patterns.
Quick Start
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_read_root():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "Hello World"}
Setup
Install dependencies:
pip install pytest pytest-asyncio httpx pytest-cov
Project structure:
project/
├── app/
│ ├── main.py
│ └── routers/
└── tests/
├── conftest.py # Copy from assets/conftest.py
└── test_*.py # Copy pattern from assets/test_api_template.py
Core Patterns
Testing CRUD Endpoints
def test_create(client, sample_data):
response = client.post("/items/", json=sample_data)
assert response.status_code == 201
assert "id" in response.json()
def test_read(client):
response = client.get("/items/1")
assert response.status_code == 200
def test_not_found(client):
response = client.get("/items/99999")
assert response.status_code == 404
Testing with Authentication
def test_protected_no_auth(client):
response = client.get("/protected/")
assert response.status_code == 401
def test_protected_with_auth(client, auth_headers):
response = client.get("/protected/", headers=auth_headers)
assert response.status_code == 200
Testing Validation
def test_invalid_input(client):
response = client.post("/items/", json={"invalid": "data"})
assert response.status_code == 422
Async Endpoint Testing
@pytest.mark.asyncio
async def test_async_endpoint(async_client):
response = await async_client.get("/async-data")
assert response.status_code == 200
Dependency Override
def test_with_mock_service(client):
def mock_service():
return MockService()
app.dependency_overrides[get_service] = mock_service
response = client.get("/service-endpoint")
app.dependency_overrides.clear()
assert response.status_code == 200
TDD Workflow
Follow the Red-Green-Refactor cycle:
1. Red: Write a Failing Test First
def test_calculate_discount():
# Write test for feature that doesn't exist yet
result = calculate_discount(price=100, percent=20)
assert result == 80.0 # This will fail - function doesn't exist
2. Green: Write Minimal Code to Pass
def calculate_discount(price: float, percent: float) -> float:
return price - (price * percent / 100)
3. Refactor: Improve While Tests Pass
def calculate_discount(price: float, percent: float) -> float:
"""Apply percentage discount to price."""
if not 0 <= percent <= 100:
raise ValueError("Percent must be between 0 and 100")
return round(price * (1 - percent / 100), 2)
TDD for FastAPI Endpoints
# Step 1: Write failing test for new endpoint
def test_search_items(client):
response = client.get("/items/search?q=test")
assert response.status_code == 200
assert "results" in response.json()
# Step 2: Implement minimal endpoint
@app.get("/items/search")
def search_items(q: str):
return {"results": []}
# Step 3: Refactor with actual search logic
Watch Mode for Rapid Feedback
# Install pytest-watch for auto-rerun on file changes
pip install pytest-watch
# Run in watch mode (re-runs tests on save)
ptw
# Watch specific directory
ptw tests/
# With verbose output
ptw -- -v
Running Tests
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run specific file
pytest tests/test_items.py
# Run with coverage
pytest --cov=app --cov-report=html
# Run async tests
pytest -v --asyncio-mode=auto
Resources
Templates (assets/)
- conftest.py - Ready-to-use fixtures for TestClient, async client, database session, auth headers
- test_api_template.py - Example test patterns for CRUD, validation, auth, and async testing
Copy templates to your tests/ directory and customize for your app.
Reference Documentation (references/)
See api_reference.md for:
- Complete fixture patterns and scopes
- Database testing with transaction rollback
- Mocking strategies
- Coverage configuration
See tdd_patterns.md for:
- Detailed red-green-refactor examples
- TDD workflow commands and watch mode
- Common TDD patterns (Arrange-Act-Assert, factory fixtures)
- Anti-patterns to avoid