如何对Django数据库迁移进行单元测试?
如何对Django数据库迁移进行单元测试?
我们已经使用django迁移(django v1.7+)更改了我们的数据库。\n数据库中存在的数据已经无效。\n基本上,我想通过在单元测试中构建预迁移数据库,添加一些数据,应用迁移,然后确认一切顺利进行来测试迁移。\n如何做到:\n
- \n
- 在加载单元测试时保留新迁移\n我在这里找到了一些关于覆盖
settings.MIGRATION_MODULES
的内容,但是我不知道如何使用。当我检查executor.loader.applied_migrations
时,它仍然列出了所有内容。我唯一能够阻止新迁移的方法是实际上删除文件;这不是我能使用的解决方案。 - 在单元测试数据库中创建一条记录(使用旧模型)\n如果我们可以阻止迁移,那么这应该很简单。
myModel.object.create(...)
- 应用迁移\n我想现在我可能可以解决这个问题,因为我找到了test_executor:设置一个指向迁移文件的计划并执行它?嗯,对吧?你有相关的代码吗?:-D
- 确认数据库中的旧数据与新模型匹配\n同样,我认为这应该很容易:只需获取迁移前创建的实例并确认它已按照正确的方式进行了更改。
\n
\n
\n
\n
\n所以挑战实际上就是弄清楚如何阻止单元测试应用最新的迁移脚本,然后在我们准备好时应用它?\n
\n也许我有错误的方法?我应该创建fixture,并在最后确认它们都正确吗?fixture是在应用迁移之前加载还是在所有迁移完成之后加载?\n
\n通过使用MigrationExecutor
和使用.migrate
选择特定的迁移,我已经可以,也许?将其回滚到特定的状态,然后逐个向前推进。但这引起了疑问;目前正在追踪sqlite的困扰,因为实际上没有ALTER TABLE指令。仍有疑问。
如何对Django数据库迁移进行单元测试?
最近,我们使用以下代码在`settings_test.py`中忽略了测试的迁移:
MIGRATION_MODULES = dict( (app.split('.')[-1], '.'.join([app, 'nonexistent_django_migrations_module'])) for app in INSTALLED_APPS )
这个想法是所有的应用都没有`nonexistent_django_migrations_module`文件夹,因此Django将找不到任何迁移。
谢谢。这确保了Django找不到任何迁移,但是似乎并没有多大帮助;如果找不到迁移,我们如何测试迁移?
显然,我误解了你的问题-你实际上想要测试迁移逻辑本身?
是的...一个测试,它创建一个迁移前的数据库,执行迁移,然后测试结果。
明白了。我认为修改标题以反映这一点将会很有帮助:)
解决方法:
- 首先,确保你的测试用例中包含了`django.test.TestCase`。
- 创建一个继承自`django.test.TestCase`的测试类。
- 在测试类中,使用`@classmethod`修饰符和`setUpClass`方法创建一个迁移前的数据库。
- 在`setUpClass`方法中,使用`django.core.management.call_command`命令来执行迁移。
- 在测试方法中,编写测试逻辑来验证迁移的结果。
下面是一个示例代码:
from django.test import TestCase from django.core.management import call_command class MigrationTestCase(TestCase): @classmethod def setUpClass(cls): super().setUpClass() # 创建迁移前的数据库 call_command('migrate', 'your_app_name', 'zero') def test_migration_logic(self): # 编写测试逻辑来验证迁移的结果 pass
通过这种方式,你可以测试迁移的逻辑,确保数据库迁移正常工作。
希望以上内容对你有所帮助!
问题的出现原因:作者在进行Django数据库迁移的单元测试时,希望能够在测试之前将数据库恢复到旧的状态,以便测试迁移过程。作者尝试了一些方法,最终找到了通过回滚到迁移历史中的旧版本来实现这一目的的方法。
解决方法:作者发现可以通过以下步骤将数据库恢复到旧的状态:
1. 使用MigrationExecutor来执行迁移历史中的旧版本:executor.migrate([("workflow_engine", "0014_nulls_permitted")])
2. 在每次执行executor.migrate
之间运行executor.loader.build_graph
方法,以确保完成迁移并使数据库行为符合预期。
3. 可以使用executor.loader.applied_migrations
方法来检查当前适用于数据库的迁移版本。
4. 可以通过直接运行SQL语句来确保数据库处于旧的状态,例如:cursor.execute('UPDATE workflow_engine_job SET next_job_state=NULL')
5. 接下来,可以运行executor.migrate([("workflow_engine", "0016_nulls_banished")])
来进行迁移。
6. 最后,可以通过编写测试来确认迁移是否成功,例如通过检查数据库中是否还有NULL值:self.assertTrue(all([j.next_job_state is not None for j in jobs]))
以上就是作者在进行Django数据库迁移的单元测试时遇到的问题以及解决方法。通过将数据库恢复到旧的状态,作者可以测试迁移过程并确保其正确性。