Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing south migrations in Django

Does anyone know a way to test the migration itself after writing it? Very many times in my DataMigrations I've found stupid subtle bugs, like True instead of False for the default value, wrong denormalizations, etc.

The default South convention is to start the migrations with numbers, so you can't even import them without using __import__. Has anyone came up upon a similar problem? How do people solve them?

The most obvious approach would be to hold the migration logic in a separate imported module and test that, but that's somewhat clunky.

like image 520
George Karpenkov Avatar asked Jan 10 '12 05:01

George Karpenkov


People also ask

Does Django test run migrations?

The Django test runner begins each run by creating a new database and running all migrations in it. This ensures that every test is running against the current schema the project expects, but we'll need to work around this setup in order to test those migrations.

What is South migration in Django?

South is a migration tool used with Django. There will be times when you would be adding fields to a model or changing the type of field (eg: Field was an IntegerField and you want to change it to FloatField). In such cases syncdb doesn't help and South comes to your rescue.


1 Answers

I stumbled into the same problem. Since I didn't find a way to do tests for datamigrations, I used assertions to detect corrupt data:

from django.conf import settings

class MyModel(models.Model):
    stupid_error = models.BooleanField(default=False)

    def __init__(self, *args, **kwargs):
        super(MyModel, self).__init__(*args, **kwargs)
        if settings.DEBUG:
            assert not self.stupid_error

Ok, it's a bit clunky. But it seems to work.

[Edit] Thinking about it again, I found a much better solution: put the tests into the DataMigration itself. Since a migration is one-off code, it doesn't have to be tested over and over.

class Migration(DataMigration):
    def forwards(self, orm):
        # lots of awesome migration code here
        # ...
        for m in orm.MyModel.objects.all():
            assert not m.stupid_error
like image 53
jammon Avatar answered Oct 17 '22 06:10

jammon