Database Django能否在每个单元测试之间刷新其数据库?

Database Django能否在每个单元测试之间刷新其数据库?,database,django,unit-testing,Database,Django,Unit Testing,Django(1.2 beta版)将在运行的每个测试之间重置数据库,这意味着每个测试都在空数据库上运行。但是,数据库未刷新。刷新数据库的效果之一是重置自动增量计数器 考虑一个通过主键从数据库中提取数据的测试: class ChangeLogTest(django.test.TestCase): def test_one(self): do_something_which_creates_two_log_entries() log = LogEntry.ob

Django(1.2 beta版)将在运行的每个测试之间重置数据库,这意味着每个测试都在空数据库上运行。但是,数据库未刷新。刷新数据库的效果之一是重置
自动增量
计数器

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

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\u one
之前运行,则日志项的主键不再是1和2,它们可能是2和3。现在,
test\u one
失败

这实际上是一个由两部分组成的问题:

  • 是否可以强制
    /manage.py test
    在每个测试用例之间刷新数据库
  • 由于Django在默认情况下不会在每个测试之间刷新DB,因此可能有一个很好的理由。有人知道吗
  • 是否可以强制./manage.py test在每个测试用例之间刷新数据库

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

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

    也许有一个很好的理由。有人知道吗

    是的,有:加速。从json刷新和重新加载许多数据需要一段时间


    也许你应该看看

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

    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])
    
    您还可以使用:

    在TransactionTestCase上设置reset\u 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)
    

    我想这是可行的,因为
    LogEntry.objects.all()
    总是以相同的顺序返回记录(增加主键),对吗?它没有定义,但很可能是。如果您想确定,只需按顺序排列结果即可id@Mike,Ivan:…或将
    ordering=('id',)
    添加到Model.meta您可以编写Daniel建议的测试类型的一种方法是使用类似
    jsonschema
    和Swagger的东西。我想还有其他方法,但这只是一种对我有效的方法。它只在数据库后端支持的情况下有效,而SQLite则不支持。
    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)