9

I'm using Django 1.7.7 with python 2.7.6 and Postgres as database and I had a problem with a TransactionTestCase. In my migrations I had two datamigrations and I wanted them to be available during the tests, so I added serialized_rollback = True to my test case (https://docs.djangoproject.com/en/1.7/topics/testing/overview/#test-case-serialized-rollback).

The first test of the test cases was ok, but then django was complaining with an IntegrityError:

IntegrityError: duplicate key value violates unique constraint "django_content_type_app_label_6032a1f08b99c274_uniq"
DETAIL:  Key (app_label, model)=(admin, logentry) already exists.

I managed to run the tests and to avoid this error by adding the following to my settings (https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-TEST_NON_SERIALIZED_APPS):

TEST_NON_SERIALIZED_APPS = ['django.contrib.contenttypes',
                            'django.contrib.auth']

But I would like to know why is this needed? Is this a bug in the rollback or is this a problem on my side?

M.javid
  • 6,387
  • 3
  • 41
  • 56
se7entyse7en
  • 4,310
  • 7
  • 33
  • 50
  • You just helped me to get around a really big problem with my TransactionTestCase test. I've never heard about TEST_NON_SERIALIZED_APPS until now. THANKS. I think this is because TransactionTestCase seems broken. My code worked with 1.7.2, it stopped on 1.7.8 without TEST_NON_SERIALIZED_APPS. I'm (slowly) moving to py.test, I somehow believe pytest-django fixtures will help me with that. Eventually. My answer for your question? I think you did everything ALL RIGHT and this whole gymnastics is required with Django 1.7 ATM. – dotz Jun 17 '15 at 14:43
  • I agree, this is a question and answer all in one. Many thanks! I am not sure why Django doesn't serialize those apps by default, because in my case it didn't work without TEST_NON_SERIALIZED_APPS set as you suggested. – tobias.mcnulty Jul 17 '15 at 18:57

1 Answers1

4

This issue is really well explained in django related ticket: https://code.djangoproject.com/ticket/23727

Quoted from there:

When using a TransactionTestCase with serialized_rollback=True, after creating the database and running its migrations (along with emitting the post_migrate signal), the contents of the database are serialized to _test_serialized_contents.

After the first test case, _fixture_teardown() would flush the tables but then the post_migrate signal would be emitted and new rows (with new PKs) would be created in the django_content_type table.

Then in any subsequent test cases in a suite, _fixture_setup() attempts to deserialize the content of _test_serialized_contents, but these rows are identical to the rows already in the database except for their PKs.

This causes an IntegrityError due to the unique constraint in the django_content_type table.

A patch has been created/released, but only for Django 1.9.x.

For previous versions, you should continue to use TEST_NON_SERIALIZED_APPS I guess...

Community
  • 1
  • 1
romgar
  • 116
  • 3