带有加载夹具的 Django 单元测试,用于解决几个相关的应用程序问题

Posted

技术标签:

【中文标题】带有加载夹具的 Django 单元测试,用于解决几个相关的应用程序问题【英文标题】:Django unit-testing with loading fixtures for several dependent applications problems 【发布时间】:2011-01-31 05:26:47 【问题描述】:

我现在正在对已经存在的代码进行单元测试。我面临下一个问题:

在运行 syncdb 创建测试数据库后,Django 会自动填充几个表,例如 django_content_type 或 auth_permissions。

然后,假设我需要运行一个复杂的测试,例如检查用户注册,这将需要大量数据表和它们之间的连接。

如果我尝试使用我现有的整个数据库来制作夹具(这对我来说相当方便) - 我会收到类似here 的错误。发生这种情况是因为 Django 已经填充了 django_content_type 之类的表。

下一个可能的方法是使用 django dumpdata --exclude 选项来填充已填充的同步数据库表。但这也不能很好地工作,因为如果我从我的数据库和用户权限表中获取用户和用户组对象,这是由 syncdb 自动创建的,我会收到错误,因为连接它们的主键现在指向错误。 here 在部分“夹具地狱”中更好地描述了这一点,但那里显示的解决方案看起来不太好)

我看到的下一个可能的方案是下一个:

    我正在运行我的测试; Django 创建测试数据库,创建 syncdb 并创建所有这些表。 在我的测试设置中,我将删除此数据库,创建新的空白数据库。 也在测试设置中从现有数据库加载数据转储

【问题讨论】:

您可以使用dumpdata --natural --exclude <django-core-apps>--natural 标志告诉 django 使用自然键来替代主 ID。例如,ContentType 模型的所有外键都将被转储为:["<app_label>", "<model_name>"],而不是:<content-type-id> 这对我帮助很大,请提供它作为答案。 【参考方案1】:

问题就这样解决了:

在syncdb创建测试数据库后,在setUp部分测试中,我使用os.system从我的代码访问shell。然后我只是加载数据库的转储,我想将其用于测试。

所以它的工作原理是这样的:syncdb 用数据填充 contenttype 和其他一些表。然后在 setUp 部分测试加载 sql 转储清除所有以前创建的数据,我得到一个不错的数据库。

可能不是最好的解决方案,但它确实有效=)

【讨论】:

在设置中我调用类似: os.system('mysql -u root -proot test_database 这使测试完全与您的特定系统相关联。这是一个很好的解决方法,但不是通用的解决方案。【参考方案2】:

我的方法是首先使用 South 来简化数据库迁移(这根本没有帮助,但很好),然后使用模型创建方法模块。

当你跑步时

  $  manage.py test my_proj

安装了 South 的 Django 创建测试数据库,并运行所有迁移以提供完全更新的测试数据库。

要编写测试,首先创建一个 python 模块调用,test_model_factory.py 在这里创建创建对象的函数。

def mk_user():
   User.objects.create(...)

然后在您的测试中,您可以导入您的 test_model_factory 模块,并为每个测试创建对象。

  def test_something(self):
     test_user = test_model_factory.mk_user()

     self.assert(test_user ...)

【讨论】:

以上是关于带有加载夹具的 Django 单元测试,用于解决几个相关的应用程序问题的主要内容,如果未能解决你的问题,请参考以下文章

加载夹具时 django unittest 出错

Django 不会为某些测试用例重新加载夹具

带有自定义用户模型加载夹具错误的 Django 项目

在 Django 中为 Selenium 测试加载夹具时出现完整性错误

如何为 LiveServerTestCase 加载夹具

使用 django rest 框架和 django oauth 工具包在单元测试中进行 oAuth 身份验证