Registry / testing / django-test-migrations

django-test-migrations

JSON →
library1.5.0pypypiunverified

django-test-migrations is a Python library designed for robustly testing Django schema and data migrations, ensuring they apply correctly, roll back safely, and maintain data integrity. It supports testing migration order and names, and works across multiple Django versions (currently 3.2, 4.1, 4.2, 5.0, 5.2). The library is actively maintained with regular updates for Python and Django version compatibility. The current version is 1.5.0, released on April 18, 2025.

pip install django-test-migrations
INSTALL
IMPORT
SIG · DJANGO-TEST-MIGRAT
D
django-test-migrations
testingpythonv1.5.0
Install
1.6s avg
Import
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.5.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.000s · 18.4MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 1.6s · import 0.000s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Migrator
from django_test_migrations import Migrator
from django_test_migrations.migrator import Migrator

The quickstart demonstrates using the `Migrator` class with `pytest` to test a specific migration. It outlines how to set up the database to an 'initial' state before the migration, create test data using the 'old' model state, apply the migration, and then assert the results using the 'new' model state. It emphasizes accessing models through `old_state.apps.get_model()` and `new_state.apps.get_model()` to ensure correct historical model versions are used.

import os import pytest from django.conf import settings # Minimal Django settings for testing if not already configured # In a real project, this would typically be in your settings.py if not settings.configured: settings.configure( INSTALLED_APPS=[ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Add your app here, e.g., 'myapp' ], DATABASES={ 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:', } }, MIGRATION_MODULES={ # Example for a hypothetical app 'myapp' # 'myapp': 'myapp.migrations' # Uncomment if your app has migrations } ) from django_test_migrations.migrator import Migrator @pytest.fixture(scope='function') def migrator(db) -> Migrator: """Provides a Migrator instance for testing against the 'default' database.""" return Migrator(database='default') def test_my_migration(migrator: Migrator): # Set up the database to a state *before* the migration you want to test # Example: app_label 'myapp', migration name '0001_initial' old_state = migrator.apply_initial_migration(('myapp', '0001_initial')) # Get the model class from the old state # Replace 'MyModel' with your actual model name OldMyModel = old_state.apps.get_model('myapp', 'MyModel') # Create some data that will be affected by the migration # Example: creating an instance with an old field value old_instance = OldMyModel.objects.create(some_old_field='value') # Apply the migration you want to test # Example: app_label 'myapp', migration name '0002_new_field' new_state = migrator.apply_tested_migration(('myapp', '0002_new_field')) # Get the model class from the new state NewMyModel = new_state.apps.get_model('myapp', 'MyModel') # Assertions: Check that the data was migrated correctly new_instance = NewMyModel.objects.get(pk=old_instance.pk) assert hasattr(new_instance, 'some_new_field') # Check for new field # assert new_instance.some_new_field == 'expected_new_value' # Optional: Test rollback # migrator.reset() # assert not NewMyModel.objects.filter(pk=old_instance.pk).exists() # Or check rolled back state
Debug
Known issues
breakingIn version 1.0.0, the `Migrator` methods `before` and `after` were renamed to `apply_initial_migration` and `apply_tested_migration` respectively. Code using the old method names will break.
fix
Update calls from `migrator.before()` to `migrator.apply_initial_migration()` and `migrator.after()` to `migrator.apply_tested_migration()`.
affects: >=1.0.0
gotchaDirectly importing models into your migration tests (e.g., `from myapp.models import MyModel`) is a common pitfall. This can lead to unexpected behavior or failures as your tests won't be using the historical model state relevant to the specific migration being tested.
fix
Always retrieve models using the provided state objects: `old_state.apps.get_model('myapp', 'MyModel')` or `new_state.apps.get_model('myapp', 'MyModel')`. This ensures you're interacting with the correct model schema at each stage of the migration test.
affects: All versions
gotchaWhen testing multiple Django applications that have interdependent migrations, you must provide `before` and `after` as a list of `(app_name, migration_name)` tuples. Additionally, when retrieving models, explicitly specify the app name (e.g., `self.get_model_before('otherapp.OtherModel')`).
fix
For multiple apps, define `before = [('app1', '0001'), ('app2', '0001')]` and `after = [('app1', '0002'), ('app2', '0002')]`. Use `self.get_model_before('app_name.MyModel')` to get models.
affects: All versions
gotchaIf your tests involve Django's `post_migrate` signals, be aware that `django-test-migrations` clears the receiver list at the start of tests and restores it afterwards. This is to prevent side effects.
fix
If you need to test your own `post_migrate` signals, attach and remove them explicitly within your test methods or setup/teardown.
affects: All versions
deprecatedSupport for older Python and Django versions has been dropped in recent releases. Specifically, Python 3.7, 3.8, and 3.9, and Django 2.2 are no longer officially supported.
fix
Upgrade your project's Python version to 3.10 or newer, and Django version to 3.2, 4.1, 4.2, 5.0, or 5.2.
affects: >=1.3.0 (Python 3.7, Django 2.2), >=1.4.0 (Python 3.8), >=1.5.0 (Python 3.9)
Upgrade
Version history
1.5.0latest on PyPI · released Apr 18, 2025
Audit
Dependencies
DjangorequiredCore framework dependency; supports Django versions 3.2, 4.1, 4.2, 5.0, 5.2.
PythonrequiredRequires Python versions >=3.10, <4.0.
typing-extensionsrequiredProvides backported and experimental type hints.
Agent activity
10 hits · last 30 days
node
10
Resources
django-test-migrations — pip install django-test-migrations · libregistry