Django可以在每个单元测试之间刷新它的数据库吗?

时间:2010-05-05 09:53:18

标签: database django unit-testing

Django(1.2 beta)将在每个运行的测试之间重置数据库,这意味着每个测试都在空DB上运行。但是,数据库不是刷新。刷新数据库的一个影响是auto_increment计数器被重置。

考虑通过主键从数据库中提取数据的测试:

class ChangeLogTest(django.test.TestCase):
    def test_one(self):
        do_something_which_creates_two_log_entries()
        log = LogEntry.objects.get(id=1)
        assert_log_entry_correct(log)
        log = LogEntry.objects.get(id=2)
        assert_log_entry_correct(log)

这将通过,因为只创建了两个日志条目。但是,如果将另一个测试添加到ChangeLogTest并且它恰好在 test_one之前运行,则日志条目的主键不再是1和2,它们可能是2 3.现在test_one失败了。

这实际上是一个两部分问题:

  1. 是否可以强制./manage.py test在每个测试用例之间刷新数据库?
  2. 由于Django默认情况下不会在每个测试之间刷新数据库,因此可能有充分的理由。有谁知道吗?

3 个答案:

答案 0 :(得分:8)

答案是,不要以依赖于特定键值的方式编写测试。例如,您的测试可以更好地编写:

def test_one(self):
    do_something_which_creates_two_log_entries()
    logs = LogEntry.objects.all()
    assert_log_entry_correct(log[0])
    assert_log_entry_correct(log[1])

答案 1 :(得分:7)

  

是否可以强制./manage.py测试在每个测试用例之间刷新数据库?

查看django.core.management.commands.flush.py命令的实现。

您可以从测试调用中调用flush命令(可能在TestCase.setUp中):

management.call_command('flush')
  

也许有充分的理由。有谁知道吗?

是的:加快速度。刷新并从json重新加载许多数据需要一段时间......

也许你应该看看TransactionTestCase

答案 2 :(得分:0)

您也可以使用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)