3

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.

3
  • 2
    Django's TestCase wraps each test in a transaction. If you don't want that, use a TransactionTestCase. Commented Oct 13, 2015 at 11:29
  • 1
    Can you show us your test and the relevant source code? Commented Oct 13, 2015 at 11:31
  • @knbk, - thanks for looking, I worked it out in the end and have added details in an answer. Commented Oct 13, 2015 at 12:02

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

oh, man, thanks so much for the tip. I've spend several days trying to fix my tests that were failing without any visible connection to recently created many-to-many field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.