Ответ
Тестирование миграций в Django — ключевая практика для обеспечения стабильности схемы БД. Основные подходы:
-
Проверка генерации миграций
Этот тест проверяет, что для текущего состояния моделей не требуется создавать новые файлы миграций. Идеально подходит для CI/CD пайплайнов.
from django.core.management import call_command from django.test import TestCase class MigrationGenerationTest(TestCase): def test_no_missing_migrations(self): # Команда завершится с ошибкой, если миграции не созданы call_command('makemigrations', check=True) -
Проверка применения и отката миграций
Тест гарантирует, что все миграции в приложении могут быть успешно применены (forward) и отменены (backward), не вызывая ошибок.
from django.core.management import call_command from django.test import TestCase class MigrationApplicationTest(TestCase): def test_migrations_can_be_applied_and_rolled_back(self): # Применяем все миграции для приложения 'my_app' call_command('migrate', 'my_app', verbosity=0) # Откатываем все миграции для 'my_app' до начального состояния call_command('migrate', 'my_app', 'zero', verbosity=0) -
Тестирование миграций данных (Data Migrations)
Если миграция изменяет данные, необходимо проверить корректность этих изменений. Тест должен создать данные в состоянии до миграции, применить миграцию и проверить, что данные были преобразованы правильно.
Для этого часто используют сторонние библиотеки, например
django-test-migrations, которая упрощает процесс.Пример с
django-test-migrations:# tests/test_migrations.py from django_test_migrations.contrib.unittest_case import MigratorTestCase class TestUserDataMigration(MigratorTestCase): # Указываем состояние БД до миграции, которую хотим протестировать migrate_from = ('users', '0005_add_user_profile') # Указываем саму миграцию migrate_to = ('users', '0006_populate_user_full_name') def prepare(self): # Создаем данные в старом формате User = self.old_state.apps.get_model('users', 'User') User.objects.create(first_name='John', last_name='Doe') def test_data_is_migrated(self): # Проверяем данные после применения миграции User = self.new_state.apps.get_model('users', 'User') user = User.objects.get(id=1) self.assertEqual(user.full_name, 'John Doe')