Testing with a database helps make sure your app works well when saving or reading data. It checks if your database code is correct and reliable.
Testing with database in FastAPI
from fastapi.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from myapp.main import app, get_db from myapp.database import Base # Create a test database engine SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db" engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) # Override the get_db dependency to use test DB def override_get_db(): db = TestingSessionLocal() try: yield db finally: db.close() app.dependency_overrides[get_db] = override_get_db client = TestClient(app)
Use a separate test database to avoid messing with real data.
Override the database dependency in FastAPI to use the test database during tests.
def test_create_item(): response = client.post("/items/", json={"name": "Test Item"}) assert response.status_code == 200 assert response.json()["name"] == "Test Item"
def test_read_items(): response = client.get("/items/") assert response.status_code == 200 assert isinstance(response.json(), list)
This example shows a FastAPI app with a simple Item model and a POST endpoint to create items. It sets up a separate test database and overrides the database dependency for testing. The test sends a request to create an item and checks the response.
from fastapi import FastAPI, Depends from fastapi.testclient import TestClient from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.orm import sessionmaker, declarative_base, Session SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db" engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() class Item(Base): __tablename__ = "items" id = Column(Integer, primary_key=True, index=True) name = Column(String, index=True) Base.metadata.create_all(bind=engine) app = FastAPI() def get_db(): db = SessionLocal() try: yield db finally: db.close() @app.post("/items/") def create_item(name: str, db: Session = Depends(get_db)): item = Item(name=name) db.add(item) db.commit() db.refresh(item) return {"id": item.id, "name": item.name} # Testing setup SQLALCHEMY_TEST_DATABASE_URL = "sqlite:///./test_test.db" test_engine = create_engine(SQLALCHEMY_TEST_DATABASE_URL, connect_args={"check_same_thread": False}) TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=test_engine) Base.metadata.create_all(bind=test_engine) def override_get_db(): db = TestingSessionLocal() try: yield db finally: db.close() app.dependency_overrides[get_db] = override_get_db client = TestClient(app) def test_create_item(): response = client.post("/items/", json={"name": "Test Item"}) assert response.status_code == 200 data = response.json() assert data["name"] == "Test Item" assert "id" in data if __name__ == "__main__": test_create_item() print("Test passed")
Always use a separate database for tests to keep your real data safe.
Use FastAPI's dependency override feature to swap the database during tests.
Run tests often to catch bugs early.
Testing with a database helps verify your app's data handling.
Use a separate test database and override dependencies in FastAPI.
Write simple tests to check creating and reading data.