Практикум: пять тестов миграций¶
Код к статье: история Alembic из четырёх ревизий для небольшого магазина, пять её вариантов с одной ошибкой в каждом и три набора тестов для каждого варианта. Нужен Docker; тестовая сессия сама запускает контейнер PostgreSQL 17.
uv venv --python 3.13 .venv
uv pip install --python .venv/bin/python "alembic-gauntlet[asyncio,testcontainers]==0.3.0" asyncpg
.venv/bin/python -m pytest -q # the clean history: 11 passed
VARIANT=drift .venv/bin/python -m pytest -q # one buggy history
.venv/bin/python run_matrix.py # every suite against every history
VARIANTS=clean,drift,drift_server_default,drift_check_missing,drift_enum_value,drift_index_missing,drift_extra_column \
.venv/bin/python run_matrix.py # the drift matrix
| Путь | Назначение |
|---|---|
shop/models.py |
ORM-модели: две таблицы, одно перечисление, соглашение об именовании |
migrations/env.py |
Контракт env.py: переданные извне соединение и схема, SET LOCAL search_path |
migrations/versions/clean/ |
Четыре ревизии в том виде, в котором их создал бы autogenerate |
migrations/versions/<bug>/ |
Те же ревизии с изменением одного файла; в BUG.txt указано, какого именно и что изменилось |
tests/test_plain_ci.py |
Типичная проверка в CI: upgrade head на пустой базе |
tests/test_by_hand.py |
Пять проверок через API Alembic; вспомогательный код — в tests/helpers.py |
tests/test_gauntlet.py |
Те же пять проверок, унаследованных от alembic_gauntlet.MigrationTestBase, плюс проверки check-ограничений и перечислений; сравнение серверных значений по умолчанию включено |
run_matrix.py |
Запуск набора тестов для каждого варианта и вывод матрицы результатов |
migrations/versions/drift_*/ |
Шесть видов расхождений схемы для статьи: тип столбца, серверное значение по умолчанию, отсутствующий индекс, лишний столбец, отсутствующее check-ограничение и изменённое перечисление |
tests/test_drift_extras.py |
Три дополнительные проверки, написанные вручную до их появления в базовом классе |
Переменная окружения VARIANT выбирает каталог migrations/versions/<variant> через параметр Alembic version_locations; по умолчанию используется clean.