【问题标题】:Cleaning up a database in django before every test method在每个测试方法之前清理 django 中的数据库
【发布时间】:2025-12-10 01:35:01
【问题描述】:

默认情况下,当 Django 针对 sqlite 后端运行时,它会创建一个新的内存数据库用于测试。这意味着对于从 unittest.TestCase 派生的每个类,我都会获得一个新数据库。可以更改它以便在运行每个测试方法之前将其清除吗?

示例:我正在测试一个在 Django 持久对象之上提供额外抽象的管理器类。代码看起来更像这样

class TestForManager(unittest.TestCase):
  def testAddingBlah(self):
    manager = Manager()
    self.assertEquals(manager.getBlahs(), 0)
    manager.addBlah(...)
    self.assertEquals(manager.getBlahs(), 1)

  def testAddingBlahInDifferentWay(self):
    manager = Manager()
    self.assertEquals(manager.getBlahs(), 0)
    manager.addBlahInDifferentWay(...)
    self.assertEquals(manager.getBlahs(), 1)

现在,第二个测试的第一个断言失败,因为数据库的状态在测试调用之间被保留,并且数据库中已经有一个 Blah 的实例。

【问题讨论】:

  • 你使用什么版本的 django?因为所有当前版本都会在每次测试方法调用时刷新数据库。
  • 0.96。也许它值得升级。我会试试这个。

标签: python django unit-testing django-models


【解决方案1】:

使用django.test.TestCase 而不是unittest.TestCase。它适用于所有主要版本的 Django!

【讨论】:

  • 根据我的经验,这只会清理默认数据库,您自己清理任何其他数据库。清理非默认数据库的最佳方法是什么?
  • 说真的,这篇文章为我节省了一个小时的时间。谢谢。
  • 设置multi_db=True 清除所有数据库(以防您使用多个数据库)
  • 永远不要说“一如既往”——你是在自找麻烦。 :-)
  • 谢谢,这是由 PyCharm 添加的 unittest.TestCase。现在与django.test.TestCase一起工作!
【解决方案2】:

您可以使用tearDown 方法。它将在您的测试运行后调用。您可以删除那里的所有 Blahs。

【讨论】:

  • 另请注意,您可以在运行测试用例之前使用setUp 设置数据库。
【解决方案3】:

使它们在两个不同的功能中都不是测试功能。最后从一个测试函数中调用依赖函数。

【讨论】:

  • 您能否添加一些简短的示例,以便更好地了解您的意思?
  • 详情请访问这里*.com/questions/39866805/…
  • 对不起,我的意思是您可以通过链接和示例来改进您的答案。换句话说,你的答案对我来说似乎不完整。
【解决方案4】:

为什么不做以下事情?这样就可以完成您需要的工作,而无需对您的代码进行重大更改。

class TestOneForManager(unittest.TestCase):
  def testAddingBlah(self):
    manager = Manager()
    self.assertEquals(manager.getBlahs(), 0)
    manager.addBlah(...)
    self.assertEquals(manager.getBlahs(), 1)

class TestTwoForManager(unittest.TestCase):
  def testAddingBlahInDifferentWay(self):
    manager = Manager()
    self.assertEquals(manager.getBlahs(), 0)
    manager.addBlahInDifferentWay(...)
    self.assertEquals(manager.getBlahs(), 1)

编辑。 “在 TestCase 上重置”功能可让您完全控制。

  • 当您拥有互不干扰的测试用例时,单个 TestCase 中的许多测试方法都很好。

  • 当您的测试用例相互干扰时,单个 TestCase 中很少有测试方法是好的。

您可以通过将测试方法分组到一个或多个 TestCases 中来选择适用于您的测试的模型。您拥有完全的控制权。

【讨论】:

  • 是的,我知道,我可以做到。但它看起来有点奇怪。将单个类的测试保留在一个 unittest.TestCase 下似乎很好。我更多的是在寻找一些可以调整 Django 做正确事情的解决方案。
  • “将单个类的测试保留在一个 unittest.TestCase 下似乎很好” 这没有令人信服的理由。最初的 unittest 设计只有一个 runTest 方法。每个案例一个测试就可以了。
【解决方案5】:

要清除非默认数据库,请在类中添加multi_db = True

例如

class MyTestCase(django.test.TestCase)
    multi_db = True

    def test_one(self):
        self.assertTrue(True)

【讨论】: