Introduction to pytest (Part 2): Fixtures, parameterized tests, and API clients
Part 1 covered plain tests. Now you add fixtures for reusable setup, parametrize for tabular cases, and FastAPI’s TestClient for HTTP-level assertions without binding ports.
📚 Prerequisites
- Pytest basics.
- FastAPI routing from Chapter 4 is helpful for the final section.
🎯 What you'll learn
- Declare fixtures with scopes (
function,module,session). - Generate combinatorial test matrices with
@pytest.mark.parametrize. - Exercise ASGI apps in-process using
TestClient.
Fixtures
import pytest
@pytest.fixture
def sample_user():
return {"name": "Ada", "id": 1}
def test_user_id(sample_user):
assert sample_user["id"] == 1
Promote expensive resources to scope="module" or scope="session" only when isolation still holds.
Parametrization
import pytest
from math_utils import add
@pytest.mark.parametrize("a,b,expected", [(1, 2, 3), (-1, 1, 0), (0, 0, 0)])
def test_add_table(a, b, expected):
assert add(a, b) == expected
Each tuple becomes an independent row in pytest’s report—ideal for validation tables supplied by product teams.
FastAPI TestClient
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
@app.get("/health")
def health():
return {"status": "ok"}
client = TestClient(app)
def test_health():
response = client.get("/health")
assert response.status_code == 200
assert response.json() == {"status": "ok"}
Use the context manager form when startup/shutdown lifecycles must fire:
with TestClient(app) as c:
assert c.get("/needs_startup").status_code == 200
Override dependencies to inject fake DB sessions:
from app import app, get_session
app.dependency_overrides[get_session] = lambda: fake_session
try:
...
finally:
app.dependency_overrides.clear()
💡 Key takeaways
- Fixtures + parametrization remove copy/paste setup while keeping tests explicit about dependencies.
- HTTP tests belong at the boundary; still unit-test pure functions deeply underneath.
➡️ Next steps
Practice red/green cycles in Test-driven development basics.