由于重复键,带有固定装置的 Django TestCase 导致 IntegrityError

Django TestCase with fixtures causes IntegrityError due to duplicate keys

我无法从 django_nose.FastFixtureTestCase 转移到 django.test.TestCase(甚至更保守的 django.test.TransactionTestCase)。我正在使用 Django 1.7.11 并且正在针对 Postgres 9.2 进行测试。

我有一个 Testcase class 可以加载三个 fixtures 文件。 class 包含两个测试。如果我 运行 将每个单独测试作为单个 运行 (manage test test_file:TestClass.test_name),则它们都有效。如果我 运行 他们在一起,(manage test test_file:TestClass),我得到

IntegrityError: Problem installing fixture '<path>/data.json': Could not load <app>.<Model>(pk=1): duplicate key value violates unique constraint "<app_model_field>_49810fc21046d2e2_uniq"

对我来说,似乎数据库实际上并没有在测试之间被刷新或回滚,因为它只发生在我 运行 单个 运行 测试中。

我已经逐步检查了 Django 代码,看起来它们 刷​​新或回滚 -- 取决于我是在尝试 TestCase 还是 TransactionTestCase.

(由于 https://github.com/django-nose/django-nose/issues/220,我要离开 FastFixtureTestCase

我还应该看什么?这似乎应该是一件简单的事情,并且正是 django.test.TestCaseDjango.test.TransactionTestCase 的设计目的。

编辑:

测试class大致是这样的:

class MyTest(django.test.TransactionTestCase):  # or django.test.TestCase                        

    fixtures = ['data1.json', 'data2.json', 'data3.json']                                                      

    def test1(self):    
        return # I simplified it to just this for now.                            

    def test2(self):
        return # I simplified it to just this for now.                                               

更新:

我已经成功地通过一次测试重现了几次,所以我怀疑夹具加载代码中有什么东西。

我的一个基本假设是我的数据库对于每个 TestCase 都是干净的。追踪到 django 核心代码,我发现了一个对象(在一种情况下 django.contrib.auth.User)已经存在的实例。

我暂时覆盖 _fixture_setup() 以断言数据库在加载固定装置之前是干净的。断言失败。

我能够将问题缩小到 TestCase.setUpClass() 而不是 TestCase.setUp() 中的代码,因此该对象泄漏出测试并与其他 TestCase 固定装置。

我完全不明白的是,我认为数据库在 TestCases 之间被删除并重新创建 -- 但也许这是不正确的。

更新:最新版本的 Django 包含 setUpTestData(),应该使用它来代替 setUpClass()