【问题标题】:Django Testcase, possible to load fixture at the class/module level?Django Testcase,可以在类/模块级别加载夹具吗?
【发布时间】:2014-02-07 05:19:56
【问题描述】:

我正在尝试将 json 固定装置加载到 Python 2.6/Django 1.4 单元测试中。我可以在测试级别使用 Django 的 TestCase,但加载需要 8-10 秒(2M 的 json,不会变得更小)。因此,运行十几个测试真的很慢,我想只加载一次测试数据库。看起来它可能在 Python 2.6 中是可能的,加上 unittest2,但我还没有让它工作。

# Works, but takes eight seconds per test.
class BaseStuff(django.test.testcases.TestCase):
    fixtures = ['test_data']

    def setUp(self):
        # stuff
    def test_one(self):
        # stuff

# Doesn't work - but runs *really* fast.
class BaseStuff(unittest2.TestCase):
    @classmethod
    def setUpClass(cls):  # Added in unittest2
        fixtures = ['test_data']
        print "in setupClass()"  # Does print, so function is called.

尝试 setupModule() 也没有用。 setup 函数肯定会被调用,但似乎不支持fixture。

所以 Django 的 TestCase 将读取夹具,而 unittest2 的 TestCase 将在类/模块级别执行操作。有没有办法结合这个操作,并在类/模块级别读取固定装置?我尝试了多重继承,但无法加载数据。

更新:根据@robjohncox 的建议,此代码在模块级别:

from django.core import management
management.call_command('loaddata', 'test_data.json', verbosity=1, noinput=True)

似乎确实创建了一个数据库。但随后 Django 似乎为每个测试创建了另一个数据库(它是空的)。不知道如何告诉 TestCase 使用第一个 db(我尝试了 Django 和 unittest2 TestCase)。

【问题讨论】:

  • 你有没有找到办法做到这一点?
  • @n00b 没有,并且有一段时间没有使用 Django。其实这是1.4版本的问题,我觉得django其实已经到了2.2了。

标签: python django unit-testing module django-fixtures


【解决方案1】:

您可以通过在setUpClass 方法中手动加载夹具数据来解决此问题 - 有一个 django 管理命令 (loaddata) 可以为您执行此操作,它可以是 called from the code。正如您在示例中正确指出的那样,这需要是 unittest2.TestCase

【讨论】:

  • 关于使用的更多信息?我尝试设置--database=test_foo,并得到connection test_foo does not exist(具有该名称的数据库确实存在)。在命令行中使用 loaddata 时的结果与在代码中相同。
  • 我认为问题在于,因为您没有使用 django TestCase,所以在运行测试时没有显式创建数据库。我认为您可以通过在运行loaddata 之前在setUpClass 方法中调用syncdb 命令(带有参数--noinput)来解决此问题。这不是我之前尝试过的技术,但听起来应该可以。希望这会有所帮助。
  • 实际上,我使用的是 Django TestCase(没有更改代码),我尝试在模块顶部和 TestCase 内部加载。将尝试syncdb - 结果,不高兴......嗯,现在我想知道它是否在settings.py中寻找数据库名称。更多测试...
  • 很抱歉听到这对您不起作用:(一旦有人可以为您提供有用的东西,就会删除答案。祝您好运。
  • 并不是说你的答案是错误的,只是它更像是一个提示。 :) 不知道您是否使用过这种方法,并且可能有更多信息。我实际上正在取得进展 - 在设置了一个假名称而不是设置数据库名称之后,它在命令行上运行。只是还没有在代码中。
【解决方案2】:

正如 Django 文档建议的那样,您可以在夹具名称中使用数据库的名称,以将数据加载到数据库中:

所以结合你的建议和我的建议:

在你的 settings.py 中,你有这个数据库:

DATABASES = {'default': ..., 'legacy_db': ...}

然后您可以像这样将夹具加载到数据库中:

from django.core import management
management.call_command('loaddata', 'test_data.legacy_db.json', verbosity=1, noinput=True)

参考:https://docs.djangoproject.com/en/dev/ref/django-admin/#database-specific-fixtures

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多