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
source to share
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:
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.
source to share
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 !)
source to share