Reputation: 17087
I've hit an issue with running tests where I'm getting TransactionManagementError as soon as I start running tests. I've tried various different tests and they all hit this error:
.ve/lib/python2.7/site-packages/django/test/testcases.py:189: in __call__
self._post_teardown()
.ve/lib/python2.7/site-packages/cms/test_utils/testcases.py:97: in _post_teardown
menu_pool.clear()
.ve/lib/python2.7/site-packages/menus/menu_pool.py:156: in clear
if to_be_deleted:
.ve/lib/python2.7/site-packages/django/db/models/query.py:145: in __nonzero__
self._fetch_all()
.ve/lib/python2.7/site-packages/django/db/models/query.py:966: in _fetch_all
self._result_cache = list(self.iterator())
.ve/lib/python2.7/site-packages/django/db/models/query.py:1202: in iterator
for row in self.query.get_compiler(self.db).results_iter():
.ve/lib/python2.7/site-packages/django/db/models/sql/compiler.py:701: in results_iter
for rows in self.execute_sql(MULTI):
.ve/lib/python2.7/site-packages/django/db/models/sql/compiler.py:787: in execute_sql
cursor.execute(sql, params)
.ve/lib/python2.7/site-packages/django/db/backends/utils.py:59: in execute
self.db.validate_no_broken_transaction()
.ve/lib/python2.7/site-packages/django/db/backends/__init__.py:386: in validate_no_broken_transaction
"An error occurred in the current transaction. You can't "
E TransactionManagementError: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
You can see the stack trace is in the _post_teardown
method, so I guess the problem is somewhere before this test. I've looked at the code on each line of the stack trace and can't see a transaction being started in those bits of the code, so it must happen before here, but how do I find out where?
Given it happens whether I test app A alone or app B alone I'm not sure how to track down the code in question. Any suggestions welcome.
I am using Django 1.7, Django CMS 3.1 (which contains the menus app in the stack trace above) and pytest as the test runner. I am for this test using the --create-db
argument to ensure the database is recreated cleanly.
Upvotes: 3
Views: 1615
Reputation: 17087
I tracked down the change by rolling back commits until the tests passed and comparing what changed. It turned out that it was adding a post save signal handler to auto-create a linked model that was the change that stopped tests passing. I have a User model, and a UserProfile model with a OneToOneField pointing at the User model.
The problem was that the tests were often manually creating the UserProfile. Once the post_save handler was added, that would lead to an error of duplicate id for the manually created UserProfile, as the automatically created UserProfile has already used that id. I guess that caused the transaction around the unit test to fail badly, leading to all the other errors.
But that original error was hidden in the noise of the many errors about transactions.
Upvotes: 4