-
Notifications
You must be signed in to change notification settings - Fork 347
Better handling of south migrations for newer versions of south. #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks for the report! We are about to release a new version of pytest-django, were most of the code is rewritten. I will revisit this issue when that release is out, the patch will probably not apply cleanly since we made some big changes to the database setup code. |
Thanks for taking a look. How long until the new version drops? |
It is released as of now! :) Can you please update the pull request for the latest master? Thanks! |
@calebbrown did you rework this issue ? |
I don't really see the point of running migrations with the test suite. It will slow down running the tests a lot. (Please prove me wrong though) To see if all migrations run, why not just drop the development database and run manage.py migrate? Also, datamigrations will likely not really test anything since the tables will all be empty, so you will probably never find problems with running data migrations with real data. What is the benefit of integrating it with the test running, rather than just running from the manage.py command? |
Actually there are a couple of cases where the migration can fail even with empty database. My thoughts on the topic are:
My position is that I'd rather have a 10% slower test suite with migration covered rather than the other way round. This being said there's an interesting alternative:
Story about why you want to test your migrations with an empty database. Then we wanted another instance of that project for production. It crashed when trying to deploy it because south tried to create a FK to a table that was to be created in a later migration. We did not see it because the later migration was already played on all our systems except the empty database. |
Testing migrations is indeed tricky. :-) Are you proposing that the test database should be created by running migrations rather than the standard syncdb way? Would that have caught the problem with the FK/migration ordering that you describe? My point is that setting up the test database with migrations to catch migration errors is very fragile. Sure, it might catch some errors, but that is more a side effect than an actual test. I check migrations by first running them locally on my dev machine. I inspect the tables and data manually to make sure it looks good. Then I push it to the staging environment with a full production database copy. I don't think these steps can be skipped even if the test database are constructed by running migrations. Third party apps that ship migrations are trickier, since they must work in all kinds of environments. I think this is basically impossible to test since there are so many things involved, and creating the test database with migrations wouldn't really help. |
For anyone who is interested, if you really want to force south to run, you can use this gist to do so: |
I needed to run South migrations because I have data migrations on which my tests depend. I didn't know about this ticket, only the blanket "migrations are not used" stated on the website, so I went ahead and fixed it independently, kind of similar to @scoarescoare's gist above. This is the monkeypatch I used:
It's important to disable the Migrations only run when using --create-db, because we use --reuse-db by default. This allows us to test that migrations leave the database in the right state, without slowing down test running most of the time, because they are not always run. Our app isn't designed to run with syncdb, so forcing it to do so is rather weird, and doesn't catch errors such as failing to create migrations for our new models for example. +1 for fixing this in
|
I am thinking of introducing a hook, something like this that could be placed in your conftest.py file: from django.core.management import call_command
def pytest_django_create_db():
call_command('migrate') There seems to be a set of different use cases to customize database setup: #37, #38, #57. @qris What are your thoughts of this? |
@pelme thanks for listening! This would work for me if:
My first version of the patch actually modified the I didn't see any way to disable the default |
Please check out my PR at #129. It is based on this PR, but also fixes handling of initial data, which is skipped in South (http://south.aeracode.org/ticket/1395#comment:3). |
This requires to monkey-patch `south.hacks.django_1_0.SkipFlushCommand`, which has a bug that prevents any initial data to be installed. South issue: http://south.aeracode.org/ticket/1395#comment:3 Fixes pytest-dev/pytest-django#22 Django code reference for 1.6, from django-1.6.x/django/db/backends/creation.py(339)create_test_db(): # Report syncdb messages at one level lower than that requested. # This ensures we don't get flooded with messages during testing # (unless you really ask to be flooded) call_command('syncdb', verbosity=max(verbosity - 1, 0), interactive=False, database=self.connection.alias, load_initial_data=False) # We need to then do a flush to ensure that any data installed by # custom SQL has been removed. The only test data should come from # test fixtures, or autogenerated from post_syncdb triggers. # This has the side effect of loading initial data (which was # intentionally skipped in the syncdb). call_command('flush', verbosity=max(verbosity - 1, 0), interactive=False, database=self.connection.alias)
Hi,
We have tests that require
south
migrations to be run. This runner currently disables them and our tests fail.In
south
>= 0.7.1 there is a helper insouth.management.commands
calledpatch_for_test_db_setup
that inspects the Django configuration for a setting and either disables migrations or handles them.This patch changes the
_disable_south_management_command()
method so that it uses this method.