-
Notifications
You must be signed in to change notification settings - Fork 347
Fix ordering of finalizers in db fixture #64
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
See https://bitbucket.org/hpk42/pytest/src/17a246750c75f5eda01d065b9c72ab9fb0f1b544/_pytest/python.py?at=default#cl-1756 pytest's addfinalizer method appends finalizers to a list, and pops them off the end to call in finish(). These two lines must be switched to prevent _post_teardown accessing the blocking CursorWrapper. It's a bit ugly in this case, but you might want to use yield_fixtures to make the ordering more explicit: ``` @pytest.yield_fixture def django_db(_django_cursor_wrapper): if ('transactional_db' not in request.funcargnames and 'live_server' not in request.funcargnames and not is_django_unittest(request.node)): from django.test import TestCase with _django_cursor_wrapper: case = TestCase(methodName='__init__') case._pre_setup() yield case._post_teardown() yield ``` It looks pretty, except for that yield at the end, which is necessary when that if case is False.
Thanks for the report! I think the order should be changed. Does this result in an actual error (i.e is a useful db cursor needed in Is it possible to create a test case which shows this error? We support older versions of pytest which does not have yield_fixture, so it has to use addfinalizer. |
We were getting
|
Alright, it looks like this only occurs when testing with a database that doesn't support transactions. We recently switched from sqlite3 to MySQL and hit upon this error. Using MySQL with the MyISAM engine will cause this error. Provided a test case. Cheers! |
I see, there is an open issue about supporting MySQL with MyISAM tables: #8 Then the real fix for the test suite is to add a new environment for MySQL/MyISAM in Travis CI. That would already have caught this error since there are a existing tests for the database setup/teardown. The reason that this has not been fixed earlier is probably because there are very few who actually uses MyISAM tables. You should probably consider InnoDB using tables instead. Albeit from being very useful in a lot of cases, having transactions in your database will speed up your test suite a lot. |
Word, we switched when we ran into this :P I'll pull out the test, then. |
Removed it. (I rebased out the commit and force pushed; would you have done it differently?) |
I would like to have Travis CI run the test suite on MyISAM tables before merging, otherwise we will never know if we break MyISAM support in the future anyways. |
I've run into this issue and spent few hours trying to figure out what was going on right after switching my app from Django 1.4 to 1.6. I've been using MyISAM, and all tests run just fine in 1.4. After reading this I've switched my tables to InnoDB to see if it made any difference, but no luck so far. Applied the patch of this PR and now tests are back on track. @pelme it'd be great if you could merge the fix. Thanks! |
@julen So you are saying that this error happens for you with InnoDB, too? Can you please provide an example or test that shows the breakage when using InnoDB? Regarding MyISAM support: Travis CI does not currently run the test suite on MySQL with MyISAM tables, so it is impossible to know if we break MyISAM compatibility in the future. If anyone is interested in pytest-django having proper support for MyISAM tables in the future - we need the test suite to continuously run the tests agains MyISAM tables. I will unfortunately not have the time to fix this in the near future, but I'll happily merge the changes instantly if anyone puts in the effort to add a MySQL/MyISAM environment to Travis! |
The error I get without the patch is exactly the same as @theY4Kman was getting above:
|
This is now merged in master. Thanks to both of you for making this happen! |
See https://bitbucket.org/hpk42/pytest/src/17a246750c75f5eda01d065b9c72ab9fb0f1b544/_pytest/python.py?at=default#cl-1756
pytest's addfinalizer method appends finalizers to a list, and pops them off the end to call in finish(). These two lines must be switched to prevent _post_teardown accessing the blocking CursorWrapper.
It's a bit ugly in this case, but you might want to use yield_fixtures to make the ordering more explicit:
It looks pretty, except for that yield at the end, which is necessary when that if case is False.