How to test a FastAPI application with pytest and TestClient
Test a FastAPI app with pytest and the built-in TestClient: build the app, share a client fixture, assert on endpoint responses, override dependencies for isolation, and measure coverage.
What you will build
FastAPI is a modern Python web framework with built-in validation and an integrated test client. You will build a small API and test its endpoints with pytest. FastAPI's TestClient wraps the app and sends requests in process, so tests are fast and need no running server. Dependency overrides let you swap real dependencies, such as a database, for test doubles.
Prerequisites
- Python 3.10 or later
- Basic FastAPI and HTTP knowledge
Steps
1. Set up the project
python -m venv .venv
source .venv/bin/activate
pip install fastapi httpx pytest
httpx backs the TestClient.
2. Build a FastAPI app
# main.py
from fastapi import FastAPI, Depends
app = FastAPI()
def get_greeting() -> str:
return "hello"
@app.get("/greet/{name}")
def greet(name: str, greeting: str = Depends(get_greeting)):
return {"message": f"{greeting}, {name}"}
3. Create a TestClient fixture
Share a client across tests with a pytest fixture.
# conftest.py
import pytest
from fastapi.testclient import TestClient
from main import app
@pytest.fixture
def client():
return TestClient(app)
4. Write endpoint tests
# test_main.py
def test_greet(client):
resp = client.get("/greet/Ada")
assert resp.status_code == 200
assert resp.json() == {"message": "hello, Ada"}
5. Override dependencies
Replace a dependency with a stub for a specific test.
from main import app, get_greeting
def test_override(client):
app.dependency_overrides[get_greeting] = lambda: "hi"
assert client.get("/greet/Ada").json()["message"] == "hi, Ada"
app.dependency_overrides.clear()
6. Run tests with coverage
pip install pytest-cov
pytest --cov=.
Verification
Run pytest and confirm both tests pass. Confirm the override test changes the greeting only for that test by running the plain test afterward and seeing the default restored. Break the route and confirm the assertion fails clearly.
Next Steps
Override the database dependency with an in-memory store, test validation errors and status codes, add parametrized cases, and run pytest in continuous integration.