4

I'm having trouble moving away from django_nose.FastFixtureTestCase to django.test.TestCase (or even the more conservative django.test.TransactionTestCase). I'm using Django 1.7.11 and I'm testing against Postgres 9.2.

I have a Testcase class that loads three fixtures files. The class contains two tests. If I run each test individually as a single run (manage test test_file:TestClass.test_name), they each work. If I run them together, (manage test test_file:TestClass), I get

IntegrityError: Problem installing fixture '<path>/data.json': Could not load <app>.<Model>(pk=1): duplicate key value violates unique constraint "<app_model_field>_49810fc21046d2e2_uniq"

To me it looks like the db isn't actually getting flushed or rolled back between tests since it only happens when I run the tests in a single run.

I've stepped through the Django code and it looks like they are getting flushed or rolled back -- depending on whether I'm trying TestCase or TransactionTestCase.

(I'm moving away from FastFixtureTestCase because of https://github.com/django-nose/django-nose/issues/220)

What else should I be looking at? This seems like it should be a simple matter and is right within what django.test.TestCase and Django.test.TransactionTestCase are designed for.

Edit:

The test class more or less looks like this:

class MyTest(django.test.TransactionTestCase):  # or django.test.TestCase                        

    fixtures = ['data1.json', 'data2.json', 'data3.json']                                                      

    def test1(self):    
        return # I simplified it to just this for now.                            

    def test2(self):
        return # I simplified it to just this for now.                                               

Update:

I've managed to reproduce this a couple of times with a single test, so I suspect something in the fixture loading code.

rrauenza
  • 6,285
  • 4
  • 32
  • 57
  • Are you sure the field you have as unique is not duplicated in the fixtures? – trinchet May 03 '16 at 19:41
  • 1
    Given that the tests work in isolation, I would say yes, I am sure. They've also been recently dumped/created from the development db. – rrauenza May 03 '16 at 20:04
  • How are you loading the fixtures? Could you post the test class? – trinchet May 03 '16 at 20:14
  • Please show fixtures and tests that can reproduce the problem. – Alasdair May 03 '16 at 20:53
  • I won't be able to in its current form as the data and structures are not mine to share. I can try reproducing this out of my app, but I'm hoping to find the root cause inside of it instead - hoping there is something obvious wrong that is a common problem. – rrauenza May 03 '16 at 23:10
  • What is really odd about this is I tried overriding TestCase._pre_setup() to dump the list of objects in the model that is having the conflict -- the list is empty. If I understand the code, this is immediately prior to loading the fixtures. It is as if the db is empty, but the index still has a conflict. – rrauenza May 03 '16 at 23:18

1 Answers1

6

One of my basic assumptions was that my db was clean for every TestCase. Tracing into the django core code I found instances where an object (in one case django.contrib.auth.User) already existed.

I temporarily overrode _fixture_setup() to assert the db was clean prior to loading fixtures. The assertion failed.

I was able to narrow the problem down to code that was in a TestCase.setUpClass() instead of TestCase.setUp(), and so the object was leaking out of the test and conflicting with other TestCase fixtures.

What I don't understand completely is I thought that the db was dropped and recreated between TestCases -- but perhaps that is not correct.

Update: Recent version of Django includes setUpTestData() that should be used instead of setUpClass()

rrauenza
  • 6,285
  • 4
  • 32
  • 57
  • 1
    I'm experiencing the same with django 1.9. Isn't this a bug? shouldn't it be reported? – sazary Mar 28 '17 at 13:21
  • 1
    No, I think my assumption was just incorrect. Note that I was accidentally creating an object in setUpClass() instead of setUp() ... so I was creating a model object in the wrong place. – rrauenza Mar 28 '17 at 17:01
  • 1
    I get the same problem, I assume each TestCase use a separate clean database, and load fixtures alone. if this is not true, how to make sure each testCase fixtures load order? – ruandao Jul 05 '19 at 13:13
  • 1
    what's your final solution? – ruandao Jul 05 '19 at 13:14
  • 1
    @ruandao I moved object creation code out of setUpClass. – rrauenza Jul 05 '19 at 14:59