【问题标题】:Django's TestCase doesn't seem to clean up database between testsDjango 的 TestCase 似乎没有在测试之间清理数据库
【发布时间】:2017-09-27 16:39:05
【问题描述】:

我编写了一个测试来检查我保存在我的设备中的数据的完整性。它是一个继承自django.tests.TestCase 的类,它声明了它需要的fixture。当我只运行此类中的方法时,它们通过了。但是,当我运行所有测试时,其他测试中的一些固定装置仍保留在数据库中,这使测试失败。我尝试了不同的变体,现在我正在覆盖setUpTestData 类方法以在测试之前杀死所有数据库数据,但这不可能。一定有更好的方法:)

class FixturesTest(TestCase):
    fixtures = ["tariff.json"]

    @classmethod
    def setUpTestData(cls):
        TariffModel.objects.all().delete()

    def test_tariff_fixtures(self):
        """Check the fixtures for tariffs"""
        ...

谢谢。

UPD:也就是说,其他一些测试确实会加载它们自己的固定装置。但我认为应该在两次测试之间放弃它们。

【问题讨论】:

  • 你能发布一个小代码示例来重现错误吗?另外,您使用的是哪个特定的 Django 版本(1.x.xx)?
  • 我升级到 1.11.5,但没有帮助。
  • 同样的问题,但仅限于 postgresql。使用 sqlite3 它确实可以清除数据库。

标签: python django testing


【解决方案1】:

我遇到了同样的问题,迟到了 2 天。对我们来说是个好消息,有几种解决方案,

解决方案 1

确保您是否覆盖了您调用super().tearDownClass() 的类方法tearDownClass。如果你覆盖tearDownClass() 而不调用它的super,它就不会调用TransactionTestCase._post_teardown() 也不会调用TransactionTestCase._fixture_teardown()。引用TransactionTestCase._post_teardown()中的文档字符串:

    def _post_teardown(self):
        """
        Perform post-test things:
        * Flush the contents of the database to leave a clean slate. If the
          class has an 'available_apps' attribute, don't fire post_migrate.
        * Force-close the connection so the next test gets a clean cursor.
        """

如果TestCase.tearDownClass() 没有通过super() 调用,那么数据库不会在测试用例之间重置,您将得到可怕的重复键异常。

解决方案 2

重写 TransactionTestCase 并设置类变量 serialized_rollback = True,如下所示:

class MyTestCase(TransactionTestCase):
    fixtures = ['test-data.json']
    serialized_rollback = True

    def test_name_goes_here(self):
        pass

引用来源:

class TransactionTestCase(SimpleTestCase):

    ...

    # If transactions aren't available, Django will serialize the database
    # contents into a fixture during setup and flush and reload them
    # during teardown (as flush does not restore data from migrations).
    # This can be slow; this flag allows enabling on a per-case basis.
    serialized_rollback = False

当 serialized_rollback 设置为 True 时,Django 测试运行器在测试用例之间回滚插入到数据库中的所有事务。还有 batta bing、batta bang……不再有重复的键错误!

您可以关注此link,了解更多详情

【讨论】:

    【解决方案2】:

    您可以通过在setUp 中调用call_commandloaddata,这样您就不必做任何Cleanup

    from django.core.management import call_command
    
    class FixturesTest(TestCase):
    
        def setUp(self):
            # Load fixtures
            call_command('loaddata', 'path/to/tariff.json')
    

    【讨论】:

      猜你喜欢
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 2017-06-15
      • 2010-09-30
      • 1970-01-01
      • 2015-06-27
      • 2017-04-09
      相关资源
      最近更新 更多