django-test-migrations icon indicating copy to clipboard operation
django-test-migrations copied to clipboard

Migrations unrelated to the migration I want to test force the migration I want to test to run before I can test state differences

Open joshua-badger opened this issue 3 years ago • 0 comments

Let's say I have three models (ModelA, ModelB, and ModelC`) across three apps. Their migrations look like this:

("my_app_a", "0001_initial")  # 1
("my_app_a", "0002_add_fields")  # 3, depends on # 1
("my_app_b", "0001_initial")   # 2
("my_app_a", "0003_migration_to_test")  # 6  <- test this one, it is not a dependency of any other migration, depends on # 3
("my_app_c", "0001_initial")  # 4
("my_app_b", "0002_add_field")  # 5, depends on # 2 and # 4

ModelB and ModelA reference each other, and that happens in ("my_app_b", "0002_add_field"). It is important to note that

Normally when I run migrations, they run in the order listed above.

I want to test that third one, so I intend to do something like this:

@pytest.mark.django_db
def test_model_state(migrator):
    old_state = migrator.apply_initial_migration(("my_app_a", "0002_add_fields"))
    ModelA = old_state.apps.get_model("my_app_a", "ModelA")
    ModelB = old_state.apps.get_model("my_app_b", "ModelB")
   ...

If I want to use that imported ModelB in the correct, I need its migrations to complete. However, if I run something like migrator.apply_initial_migration([("my_app_a", "0002_add_fields"), ("my_app_b", "0002_add_field")]), the migrations for my_app_a don't stop at 0002_add_fields, but erroneously ALSO apply ("my_app_a", "0003_migration_to_test") (which upends the point of the test). This is because the normal order is to apply everything in that list, up to ("my_app_b", "0002_add_field").

Is there a way to prevent a migration from running, as long as it's not a dependency of a different migration?

joshua-badger avatar Aug 12 '22 23:08 joshua-badger