【问题标题】:Why django checks whether settings.DATABASE_NAME db actually exists for running testcases?为什么 django 检查 settings.DATABASE_NAME db 是否确实存在用于运行测试用例?
【发布时间】:2010-10-11 14:55:00
【问题描述】:
我会经常为我的 django 项目运行测试用例。但是一个
美好的一天,我突然想到 django 实际上检查了
settings.DATABASE_NAME db 在运行测试用例时实际存在。
为什么会这样。所有我以为是 django 将采取
settings.DATABASE_NAME 并创建一个名为“test_”的测试数据库 +
设置.DATABASE_NAME。它还检查数据库是否与
name = settings.DATABASE_NAME,是否实际存在(对于
创建测试数据库)?理想情况下,只应检查名称
但不是db的实际存在对吗?
我浏览了 django 源代码,发现用于创建 testdb 的“连接”实际上是使用 DATABASE 设置选项创建的。它应该被设置的值而不是它们的实际存在所困扰。对吧?
【问题讨论】:
标签:
database
django
testing
【解决方案1】:
很好的问题……你知道,我从来没有想到过。简短的回答是 Django 本身需要验证 DATABASE_NAME 确实存在,但它确实需要连接到数据库才能创建测试数据库。大多数数据库接受(并且有些需要)DATABASE_NAME 以制定连接字符串;这通常是因为您要连接的数据库名称会影响您的连接会话的权限。
因为 test 数据库还不存在,django 必须先使用普通的 settings.DATABASE_NAME 连接才能创建 test 数据库。
所以,它是这样工作的:
- Django 的测试运行程序传递给特定于后端的数据库处理程序
- 后端特定的数据库处理程序有一个名为
create_test_db 的函数,它将使用正常设置连接到数据库。它使用一个普通的cursor = self.connection.cursor() 命令来执行此操作,该命令显然使用了正常的设置值,因为它知道此时存在的所有值。
- 连接到数据库后,特定于后端的处理程序将发出带有新测试数据库名称的
CREATE DATABASE 命令。
- 后端特定的处理程序关闭连接,然后返回到测试运行程序,它将正常的
settings.DATABASE_NAME 替换为 test_database_name
- 然后测试将正常运行。对
connection.cursor() 的所有后续调用都将使用普通设置模块,但现在该模块已换出数据库名称
- 最后,测试运行程序在调用后端特定处理程序的
destroy_test_db 函数后恢复旧的数据库名称。
如果您有兴趣,主要部分的相关代码在 django.db.backends.creation 中。看看_create_test_db 函数。
我认为 Django 设计人员可以逐个数据库地进行例外处理,因为并非每个数据库都需要连接字符串中的当前数据库名称,但这需要进行一些重构。现在,create_test_db 函数实际上在 backend 基类之一中,并且大多数实际的后端处理程序都不会覆盖它,因此有相当多的代码要推送到下游并在每个后端复制。