Why do object primary keys grow between tests in Django?

class MyClassTest(TestCase):
    def setUp(self):
        Someclass.objects.create()

    def test_first_test(self):
        # Here, Someclass.objects.all()[0].pk -> returns 1

    def test_second_test(self):
       # Here, Someclass.objects.all()[0].pk -> returns 2 !!! (bad !)

      

With the method, the SetUp()

data must be cleaned up and recreated between each test. So why do ids increase from one test to another? This is not obvious to me.

This way, I cannot do ID-based tests (as they depend on other tests). This is why I would like to get the result 1

as the result.

Please note that I have no problem with the data itself, the old data cleans well from one test to the next. The only problem is ids.

I read here django object ids increment between unit tests that the problem is with the database, not Django, but is there any trick in Django to change this

+3


source to share


3 answers


You will most likely clear the data, including the data in your database. This is not the same as recreating a database or recreating sequences. If the strings remain, they will pick up where they left off.



+2


source


There is a warning in the test documentation:

https://docs.djangoproject.com/en/dev/topics/testing/overview/

Warning. If your tests depend on database access, for example create, or you should create your test classes as subclasses of django.test.TestCase and not unittest.TestCase.

Using unittest.TestCase avoids the overhead of running each test in a transaction and cleaning up the database, but if your tests interact with the database, their behavior will depend on whether the runner is executing them. This can lead to single tests that pass on startup in isolation, but fail on startup in a package.

Are you using django.test.TestCase

or unittest.TestCase

?

If you need to support PK integrety there seems to be an option you can try:



https://docs.djangoproject.com/en/dev/topics/testing/advanced/#django.test.TransactionTestCase.reset_sequences

The setting reset_sequences = True

in TransactionTestCase ensures that sequences are always reset before test run:

class TestsThatDependsOnPrimaryKeySequences(TransactionTestCase):
    reset_sequences = True

    def test_animal_pk(self):
        lion = Animal.objects.create(name="lion", sound="roar")
        # lion.pk is guaranteed to always be 1
        self.assertEqual(lion.pk, 1)

      

Since it django.test.LiveServerTestCase

appears to be a subclass TransactionTestCase

, this should probably work for you.

+2


source


this might also work for you

class MyClassTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.x = Someclass()
        cls.x.save()

    def test_first_test(self):
        # Here, Someclass.objects.all()[0].pk -> returns 1

    def test_second_test(self):
       # Here, Someclass.objects.all()[0].pk -> returns 1 !!! (good !)
       # Here, self.x.pk -> returns 1 !!! (good !)

      

-1


source







All Articles