FastAPI для начинающих: API с базой данных и тестамиТесты вместо ручного прокликиванияFixtures, временная база и dependency override

Fixtures, временная база и dependency override

Уроки курсаFixtures, временная база и dependency override

В прошлом уроке TestClient отправлял запросы к читающему приложению без базы данных — это позволяло не думать об изоляции. Теперь цель другая: протестировать сохраняющий API с SQLite, и каждый тест должен работать с чистой базой, не видеть данные соседнего теста и не трогать рабочий файл базы.

Fixture client: подготовка и завершение вокруг одного теста

В pytest fixture — это функция, которую тест просит подготовить ресурс. Запрос выглядит максимально просто: достаточно добавить параметр с именем fixture в сигнатуру теста.

def test_empty_rooms(client):
    ...

def test_create_room(client):
    ...

Параметр client — это и есть запрос. pytest находит fixture с именем client, запускает её и передаёт результат в тест.

Функция fixture помечается декоратором @pytest.fixture. Внутри — структура с yield: код до yield готовит ресурс, yield передаёт его тесту, код после yield завершает работу ресурса.

Порядок действий fixture (это схема, не Python-код):

Подготовить временную базу и клиент
Передать клиент тесту через yield
После теста освободить ресурсы в finally

По умолчанию применяется scope="function": каждый тест получает отдельный запуск fixture от начала до конца. Если два теста запрашивают client, fixture запустится дважды — для первого теста, потом для второго. Это принципиально: данные, созданные в первом тесте, не попадают во второй, потому что второй тест получает свою базу от своего запуска fixture.

Завершение гарантируется блоком try/finally: если тест падает на assert, код в finally всё равно выполняется. Это важно для освобождения файлов и соединений. Гарантия действует при обычных ошибках и падениях assert; принудительное завершение процесса этой гарантии не даёт.

Один момент, который легко упустить: новый TestClient сам по себе не обнуляет базу данных. Он вызывает приложение внутри процесса и не подменяет используемое им хранилище. Если бы все тесты работали с одним и тем же файлом базы, запись из первого теста была бы видна во втором — независимо от того, создаётся ли новый TestClient. Изоляцию обеспечивает именно fixture, которая каждый раз создаёт новый временный файл.