使用py.test,LiveServerTestCase后不会重置数据库

时间:2015-10-07 16:57:35

标签: python django unit-testing pytest django-testing

我有许多Django测试,通常使用py.test运行它们。我最近在新文件foo(() -> { // do something }); 中添加了一个新的测试用例。此测试用例使用test_selenium.pyLiveServerTestCase类(这是我的第一个,通常我只使用StaticLiveServerTestCase)。

在这个新文件中添加这一批新测试导致后续测试在py.test中失败(在它们全部通过之前)。在py.test中TestCase之后,数据库似乎没有“重置”。我可以告诉我,因为模型的LiveServerTestCase值增加了。

当我使用Django测试运行器运行这些测试时,它们都会通过,pk在后​​续测试中重置;在py.test测试运行器中,pkpk运行后的后续测试中递增。所以如果我在我的测试中硬编码来创建一个对象并根据LiveServerTestCase检索它我期望它失败,因为Django和py.test之间的数据库不同。

为什么会出现这种情况以及如何解决这个问题?

导致数据库行为的新测试:

pk

1 个答案:

答案 0 :(得分:5)

LiveServerTestCase及其子类StaticLiveServerTestCase都继承自TransactionTestCase,它与TestCase的不同之处在于它在测试用例tearDown上重置数据库的方式。以下是上述文件的引用:

  

Django的 TestCase 类(如下所述)利用数据库事务工具来加速在每次测试开始时将数据库重置为已知状态的过程。然而,其结果是某些数据库行为无法在Django TestCase 类中进行测试。例如,您无法测试在事务中正在执行的代码块,这在使用select_for_update()时是必需的。在这些情况下,您应该使用 TransactionTestCase

     除了数据库重置为已知状态的方式以及测试代码测试提交和回滚效果的能力之外,

TransactionTestCase TestCase 是相同的:

     
      
  • TransactionTestCase 在测试运行后通过截断所有表来重置数据库。 TransactionTestCase 可以调用commit和rollback,并观察这些调用对数据库的影响。

  •   
  • 另一方面, TestCase 不会在测试后截断表。相反,它将测试代码包含在数据库事务中,该事务在测试结束时回滚。这可以保证测试结束时的回滚将数据库恢复到其初始状态。

  •   

正如您所提到的,您会看到PK计数器保留。这是因为截断表意味着丢弃所有行,但这通常意味着PK计数器被重置。

我假设你关心这个,因为你通过指定PK来使用断言对象(例如assert YourModel.objects.filter(pk=1).exists()

相反,我建议在你的测试中,你断言X对象的存在(例如assert YourModel.objects.count() == 1,或者甚至断言你期望存在的特定对象),然后像你通常那样在你的测试中使用这些对象