Базовый тест endpoint
Для синхронных тестов создают объект TestClient, передавая в него FastAPI-приложение. Его интерфейс похож на HTTP-клиент: можно вызвать get(), post() и проверить ответ через обычные assertions pytest.
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_read_healthcheck():
response = client.get('/health')
assert response.status_code == 200
assert response.json() == {'status': 'ok'}
Fixture для клиента
В большом проекте client обычно создают как pytest fixture в conftest.py.
import pytest
from fastapi.testclient import TestClient
from app.main import app
@pytest.fixture
def client():
with TestClient(app) as test_client:
yield test_client
Контекстный менеджер особенно важен, если приложение использует lifespan: он запускает и корректно завершает ресурсы приложения во время теста.
Переопределение dependencies
Тесты не должны зависеть от production-базы, внешних API или реальной аутентификации. FastAPI позволяет заменить dependency тестовой реализацией через app.dependency_overrides.
def get_test_db():
yield test_session
app.dependency_overrides[get_db] = get_test_db
def test_create_article(client):
response = client.post(
'/articles',
json={'title': 'Test article', 'text': 'Content'},
)
assert response.status_code == 201
assert response.json()['title'] == 'Test article'
app.dependency_overrides.clear()
Что проверять
status code и формат JSON-ответа;
валидацию некорректных входных данных;
аутентификацию и права доступа;
ошибки доменной логики;
побочные эффекты в базе и внешних интеграциях через mocks или тестовые реализации.
Как ответить на собеседовании
Я использую TestClient и pytest для вызова endpoints без отдельного сервера, проверяю status code и JSON. Для изоляции тестов переопределяю dependencies базы, текущего пользователя и внешних клиентов через app.dependency_overrides; если есть lifespan, создаю TestClient через context manager.