我有许多Django测试,通常使用py.test运行它们。我最近在新文件foo(() -> { // do something });
中添加了一个新的测试用例。此测试用例使用test_selenium.py
和LiveServerTestCase
类(这是我的第一个,通常我只使用StaticLiveServerTestCase
)。
在这个新文件中添加这一批新测试导致后续测试在py.test中失败(在它们全部通过之前)。在py.test中TestCase
之后,数据库似乎没有“重置”。我可以告诉我,因为模型的LiveServerTestCase
值增加了。
当我使用Django测试运行器运行这些测试时,它们都会通过,pk
在后续测试中重置;在py.test测试运行器中,pk
在pk
运行后的后续测试中递增。所以如果我在我的测试中硬编码来创建一个对象并根据LiveServerTestCase
检索它我期望它失败,因为Django和py.test之间的数据库不同。
为什么会出现这种情况以及如何解决这个问题?
pk
答案 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
,或者甚至断言你期望存在的特定对象),然后像你通常那样在你的测试中使用这些对象