한양과학기술고등학교

에듀테크 프로젝트 대시보드

테스트

TestClient pytest dependency_overrides httpx.AsyncClient 테스트 DB

FastAPI 는 테스트가 쉽습니다. 의존성 오버라이드로 DB·인증·설정을 갈아끼웁니다.

1. TestClient (동기)

pip install pytest httpx
# tests/test_items.py
from fastapi.testclient import TestClient
from app.main import app

client = TestClient(app)

def test_read_item():
    r = client.get("/items/1")
    assert r.status_code == 200
    assert r.json()["id"] == 1

def test_create_item():
    r = client.post("/items", json={"name": "pen", "price": 500})
    assert r.status_code == 201

2. DB 의존성 오버라이드

# tests/conftest.py
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from app.database import Base
from app.deps import get_db
from app.main import app

engine = create_engine("postgresql+psycopg://school:secret@localhost/school_test")
TestingSession = sessionmaker(bind=engine)

@pytest.fixture(autouse=True)
def _schema():
    Base.metadata.create_all(engine)
    yield
    Base.metadata.drop_all(engine)

@pytest.fixture
def db():
    s = TestingSession()
    try:
        yield s
    finally:
        s.close()

@pytest.fixture(autouse=True)
def _override(db):
    app.dependency_overrides[get_db] = lambda: db
    yield
    app.dependency_overrides.clear()

3. 인증 우회

from app.deps import get_current_user

@pytest.fixture
def as_admin():
    app.dependency_overrides[get_current_user] = lambda: User(id=1, is_admin=True)
    yield
    app.dependency_overrides.pop(get_current_user, None)

4. 비동기 앱 테스트

import pytest, httpx
from httpx import ASGITransport
from app.main import app

@pytest.mark.anyio
async def test_async():
    transport = ASGITransport(app=app)
    async with httpx.AsyncClient(transport=transport, base_url="http://test") as ac:
        r = await ac.get("/posts")
    assert r.status_code == 200

@pytest.fixture
def anyio_backend():
    return "asyncio"

5. lifespan 까지 태우기

with TestClient(app) as client:      # with 블록이 lifespan startup/shutdown 실행
    r = client.get("/")

6. 테스트 DB 준비

CREATE DATABASE school_test OWNER school;

SQLite(sqlite://) 로도 빠르게 돌릴 수 있지만, PostgreSQL 전용 기능(JSONB, ARRAY, ON CONFLICT)을 쓰면 실제 PostgreSQL 로 테스트하세요.

"API 스키마는 코드가 곧 문서다 (/docs)"