FastAPI: From Basics to Production · Testing FastAPI Applications
Testing with TestClient and pytest
Write fast API tests that run in-process.
fastapi.testclient.TestClient (built on httpx) calls your app in-process — no server needed. Use it with pytest fixtures, assert on status codes and JSON, and use it as a context manager (with TestClient(app) as client) so lifespan startup/shutdown run. Organize fixtures in conftest.py.
# tests/conftest.py
import pytest
from fastapi.testclient import TestClient
from app.main import app
@pytest.fixture
def client():
with TestClient(app) as c: # runs lifespan
yield c
# tests/test_health.py
def test_health(client):
resp = client.get("/health")
assert resp.status_code == 200
assert resp.json() == {"status": "ok"}
def test_validation_error(client):
resp = client.get("/books/not-a-number")
assert resp.status_code == 422
assert resp.json()["detail"][0]["loc"] == ["path", "book_id"]
Common pitfalls
- Not using the context manager, so lifespan resources aren't created.
- Tests depending on each other's data.
- Only testing happy paths.
Key points
- In-process testing with TestClient
- Context manager runs lifespan
- Test validation and error paths
Further reading: FastAPI: Testing
Practice questions
Why use with TestClient(app) as client?
Answer
Entering the context triggers lifespan startup (creating pools/clients) and exiting runs shutdown, matching production behavior.
Does TestClient need a running server?
Answer
No. It sends requests directly to the ASGI app in-process, making tests fast.
Open in the app to mark lessons complete, take notes and track your progress.