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

时间:2014-10-31 00:19:42

标签: 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 !)

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

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

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

我在这里读到django object ids increment between unit tests这个问题与数据库有关,而不是Django,但Django有没有改变它的技巧?

3 个答案:

答案 0 :(得分:5)

测试文档中有一条警告:

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/en/dev/topics/testing/advanced/#django.test.TransactionTestCase.reset_sequences

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

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)

因为,django.test.LiveServerTestCase似乎是TransactionTestCase的子类,这可能适合你。

答案 1 :(得分:2)

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

答案 2 :(得分:-1)

这对你也有用

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 !)