为什么对象主键在Django的测试之间递增?

Dav*_* D. 6 python django unit-testing factory-boy

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 !)
Run Code Online (Sandbox Code Playgroud)

使用SetUp()方法,应该清除数据并在每次测试之间重新创建.那么,为什么id从一个测试增加到另一个测试呢?这对我来说并不明显.

这样我就无法根据id进行测试(因为它们取决于其他测试).这就是为什么我总是希望得到1结果.

请注意,我对数据本身没有任何问题,旧数据可以从一个测试清除到另一个测试.问题只是ids.

我在这里读到django对象id在单元测试之间递增,问题与​​数据库有关,而不是与Django有关,但Django有没有改变它的技巧?

mon*_*kut 6

测试文档中有一个警告:

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

警告如果测试依赖于数据库访问(例如创建或查询模型),请确保将测试类创建为django.test.TestCase而不是unittest.TestCase的子类。

使用unittest.TestCase可以避免在事务中运行每个测试并刷新数据库的开销,但是如果您的测试与数据库交互,则其行为将根据测试运行者执行它们的顺序而有所不同。这可能导致单元测试在单独运行时通过,但在套件中运行时失败。

您在使用django.test.TestCase还是unittest.TestCase

如果您需要保持PK完整性,那么似乎可以尝试以下方法:

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

reset_sequences = True在TransactionTestCase上进行设置将确保在测试运行之前始终重置序列:

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)
Run Code Online (Sandbox Code Playgroud)

由于django.test.LiveServerTestCase似乎是子类,TransactionTestCase这可能应该为您工作。


M. *_*ter 4

您很可能正在清除数据,包括数据库中的数据。这与重新创建数据库或重新创建序列不同。如果序列仍然存在,它们将从中断处继续。