如何对 Django South“数据迁移”进行单元测试

Posted

技术标签:

【中文标题】如何对 Django South“数据迁移”进行单元测试【英文标题】:How to unit test a Django South "datamigration" 【发布时间】:2011-06-15 07:48:40 【问题描述】:

我使用 south 创建了一个数据迁移,它采用版本表并将其转换为:

major: 1, minor: 2, micro: 3, release: a

变成更简单的:

name: 1.2.3.a

现在我想使用 django 单元测试 (1.3beta) 来测试这个数据迁移。

如何以编程方式使用 south 来向前和向后滚动迁移,同时指定要使用的自定义装置,我可以验证?

【问题讨论】:

【参考方案1】:

我在 Django South IRC 上问过这个问题,但没有真正得到答案;他们确实让我质疑单元测试数据迁移的“原因”(因为它通常是一次性的事情,而且您无论如何都不会重构它,所以您不妨进行一些手动检查)。

但是,我找到了“真正测试”的 2 个理由:

事先写下我的假设会迫使我明确表达,因此更有可能是正确的。 除了实际代码(对于相当大的数据迁移而言,这很复杂)之外,我可以在其他地方阅读有关假设

最后,我只是决定在数据迁移结束时添加一些断言(即常规 python 语句)。这具有上述优点,并且如果其中一个断言失败并准确告诉您现实的哪一部分与您预期的不一样,则进行回滚的额外优势。

【讨论】:

我认为你所说的确切地知道迁移失败的位置和原因(使用测试)远比简单地回滚要好得多......南方应该为此做好准备......我在网上找到了这个解决方案:micknelson.wordpress.com/2013/03/01/testing-django-migrations【参考方案2】:

这并不是真正的单元测试:它是某种其他类型的测试...这意味着您可能不得不在正常的单元测试框架之外寻找——尽管您当然可以使用 em> 现有的工具来构建你想要的东西。

我要做的是从我的常规 django 测试中创建一个全新的测试套件,并在每个测试中定义一个属性来定义它的“寿命”:您希望它通过的第一次和最后一次迁移。

然后,编写一个基本上可以做到这一点的脚本:

for m in range(latestMigrationNumber):
    name = findNameOfMigrationNumber(m)   # look in the migrations directory
    executeMigration(name)                # os.system(), subprocess.*, etc
    runTheTests()

您可以使用装饰器为每个测试指定“寿命”,也许通过扩展 this "enable/disable" decorator concept 来比较当前迁移编号(您必须将其全局存储在某处)与您希望通过的测试,并且让它交换通过/失败结果(因此,如果测试在其生命周期之外通过,装饰器会使其失败,反之亦然)。

要测试向后迁移,只需使用相同的方案,但向后运行循环。

【讨论】:

以上是关于如何对 Django South“数据迁移”进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

Django South 迁移不适用于 null = True 和空白 = True

将 Django South 与多个代码分支一起使用的工作流程

无法在 Django 1.7 中创建 South 数据库模型

使用 django 迁移,如何更改 auth_permission 字段长度?

SQL Server 的数据库迁移

Django 数据迁移