【问题标题】:Django TestCase with fixtures causes IntegrityError due to duplicate keys带有固定装置的 Django TestCase 由于重复键而导致 IntegrityError
【发布时间】:2016-05-03 19:21:48
【问题描述】:

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

我有一个Testcase 类,可以加载三个夹具文件。该类包含两个测试。如果我将每个测试单独运行为单次运行 (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 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.                                               

更新:

我已经通过一次测试成功地重现了这几次,所以我怀疑夹具加载代码中存在某些问题。

【问题讨论】:

  • 您确定您拥有的唯一字段在灯具中没有重复吗?
  • 鉴于测试是独立进行的,我敢肯定。它们最近也已从开发数据库中转储/创建。
  • 你是如何加载灯具的?可以发一下测试课吗?
  • 请展示可以重现问题的夹具和测试。
  • 我无法以目前的形式进行分享,因为数据和结构不是我要分享的。我可以尝试在我的应用程序中重现此问题,但我希望找到其中的根本原因 - 希望有一些明显的错误是常见问题。

标签: django django-testing django-nose


【解决方案1】:

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

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

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

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

更新:最新版本的 Django 包括应该使用的 setUpTestData() 而不是 setUpClass()

【讨论】:

  • 我在使用 django 1.9 时遇到了同样的情况。这不是一个错误吗?不应该举报吗?
  • 不,我认为我的假设是不正确的。请注意,我不小心在 setUpClass() 而不是 setUp() 中创建了一个对象......所以我在错误的地方创建了一个模型对象。
  • 我遇到了同样的问题,我假设每个 TestCase 都使用一个单独的干净数据库,并且单独加载夹具。如果不是这样,如何确保每个 testCase 固定装置的加载顺序?
  • 你的最终解决方案是什么?
  • @ruandao 我将对象创建代码移出 setUpClass。
猜你喜欢
  • 2012-08-05
  • 2020-04-01
  • 1970-01-01
  • 2018-03-18
  • 2021-02-08
  • 1970-01-01
  • 2013-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多