FastAPI: From Basics to Production · Testing FastAPI Applications

Integration Tests with a Real Database

Run tests against PostgreSQL with migrations and per-test isolation.

Create a free account to save this page, take notes and track your progress. Sign in

Test against the same database engine as production (PostgreSQL via Docker, Testcontainers or a CI service). Apply Alembic migrations once per session, then isolate each test: run it inside a transaction that's rolled back (binding the session to a connection with an outer transaction), or truncate tables. Override the get_db dependency to use the test session.

import pytest
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from app.db import get_db
from app.main import app

engine = create_async_engine(TEST_DATABASE_URL)


@pytest.fixture
async def db():
    async with engine.connect() as conn:
        trans = await conn.begin()
        session = AsyncSession(bind=conn, join_transaction_mode="create_savepoint", expire_on_commit=False)
        app.dependency_overrides[get_db] = lambda: session
        try:
            yield session
        finally:
            await session.close()
            await trans.rollback()          # undo everything the test did
            app.dependency_overrides.pop(get_db, None)

Common pitfalls

  • Using SQLite to test PostgreSQL-specific SQL.
  • Tests that commit for real and pollute later tests.
  • Creating schemas with create_all instead of running migrations (migrations go untested).

Key points

  • Same engine as production
  • Rollback-per-test isolation
  • Run real migrations

Further reading: SQLAlchemy: joining an external transaction

Practice questions

How can app code that calls commit() be rolled back in tests?

Answer

Bind the session to a connection with an outer transaction and use join_transaction_mode='create_savepoint'; app commits release savepoints while the outer transaction is rolled back after the test.

Why run Alembic migrations in tests instead of Base.metadata.create_all?

Answer

It verifies the migrations themselves and ensures the test schema matches production exactly.

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?