Django 测试运行程序不尊重 unittest.TestCase?
Django test runner not respecting unittest.TestCase?
对于我的一个功能测试,我决定使用 unittest.TestCase
而不是 Django 测试 class 因为清理测试时直接访问我的本地开发数据库很方便测试本身。
运行 隔离测试像我预期的那样通过了:
$ python manage.py test functional_tests.test_functionality
System check identified no issues (0 silenced).
...
----------------------------------------------------------------------
Ran 3 tests in 0.040s
OK
然而,当我尝试同时 运行 所有测试时,该测试特别出错,抱怨对象 DoesNotExist
,就好像它正在使用 Django 测试数据库一样:
$ python manage.py test functional_tests
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..................E..
======================================================================
ERROR: some_functional_test (functional_tests.test_functionality.FunctionalTest)
----------------------------------------------------------------------
Traceback (most recent call last):
... etc.
app.models.Object.DoesNotExist: Object matching query does not exist.
----------------------------------------------------------------------
Ran 21 tests in 0.226s
FAILED (errors=1)
Destroying test database for alias 'default'...
我认为当 Django 的测试数据库中不存在 Object
时我尝试使用 Object.objects.latest('created')
时出现错误。
有什么方法可以防止 Django 将所有测试包装在关于测试 运行ner 的所有测试中,从而阻止我的测试直接访问 Object
?
先稍微解释一下。
默认情况下,当您 运行 ./manage.py test
django test-runner 执行一些涉及创建测试数据库的步骤时(每个数据库名称都带有 test_
前缀,来自 app settings), running migration and destroying test database (more details on runner steps could find here)
描述了django如何处理测试数据库的一个很好的解释here
在您 运行 unittest.TestCase
孤立的情况下 没有 创建测试数据库:
$ python manage.py test functional_tests.test_functionality
System check identified no issues (0 silenced).
...
----------------------------------------------------------------------
Ran 3 tests in 0.040s
OK
(^没有关于创建测试数据库的日志)
那是因为没有 django.test.TestCase
调用。从sources (virgin unittest.TestCase
doesn't have databases
property, when django.TestCase it has)
可以看出
但是当您调用整个模块 (python manage.py test functional_tests
) 时,您似乎在套件中进行了一些 django.test.TestCase
测试,这就是创建新测试数据库的原因:
$ python manage.py test functional_tests
Creating test database for alias 'default'... # <-- THIS ONE
##<skipped for readability>
Destroying test database for alias 'default'...
正如您提到的,测试失败是因为没有为它们准备好的对象。
解决方案
此时我看到解决这个问题的选项很少。
明确地为测试准备测试数据(通过 fixtures 或在测试或设置中手动)以便它们独立于数据库的当前状态
明确使用所需的数据库。
运行 使用 --keepdb
选项进行测试(即 ./manage.py test --keepdb
,它将使用现有数据库并且不会在测试 运行s 后销毁它)并设置相同的 test database name in app settings as working database(在这种情况下,它不会为测试数据库附加 test_
前缀)
既然不想用django.TestCase
,那干脆不用?用 unittest.TestCase
替换它们,它不会创建测试数据库
对于我的一个功能测试,我决定使用 unittest.TestCase
而不是 Django 测试 class 因为清理测试时直接访问我的本地开发数据库很方便测试本身。
运行 隔离测试像我预期的那样通过了:
$ python manage.py test functional_tests.test_functionality
System check identified no issues (0 silenced).
...
----------------------------------------------------------------------
Ran 3 tests in 0.040s
OK
然而,当我尝试同时 运行 所有测试时,该测试特别出错,抱怨对象 DoesNotExist
,就好像它正在使用 Django 测试数据库一样:
$ python manage.py test functional_tests
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..................E..
======================================================================
ERROR: some_functional_test (functional_tests.test_functionality.FunctionalTest)
----------------------------------------------------------------------
Traceback (most recent call last):
... etc.
app.models.Object.DoesNotExist: Object matching query does not exist.
----------------------------------------------------------------------
Ran 21 tests in 0.226s
FAILED (errors=1)
Destroying test database for alias 'default'...
我认为当 Django 的测试数据库中不存在 Object
时我尝试使用 Object.objects.latest('created')
时出现错误。
有什么方法可以防止 Django 将所有测试包装在关于测试 运行ner 的所有测试中,从而阻止我的测试直接访问 Object
?
先稍微解释一下。
默认情况下,当您 运行 ./manage.py test
django test-runner 执行一些涉及创建测试数据库的步骤时(每个数据库名称都带有 test_
前缀,来自 app settings), running migration and destroying test database (more details on runner steps could find here)
描述了django如何处理测试数据库的一个很好的解释here
在您 运行 unittest.TestCase
孤立的情况下 没有 创建测试数据库:
$ python manage.py test functional_tests.test_functionality
System check identified no issues (0 silenced).
...
----------------------------------------------------------------------
Ran 3 tests in 0.040s
OK
(^没有关于创建测试数据库的日志)
那是因为没有 django.test.TestCase
调用。从sources (virgin unittest.TestCase
doesn't have databases
property, when django.TestCase it has)
但是当您调用整个模块 (python manage.py test functional_tests
) 时,您似乎在套件中进行了一些 django.test.TestCase
测试,这就是创建新测试数据库的原因:
$ python manage.py test functional_tests
Creating test database for alias 'default'... # <-- THIS ONE
##<skipped for readability>
Destroying test database for alias 'default'...
正如您提到的,测试失败是因为没有为它们准备好的对象。
解决方案
此时我看到解决这个问题的选项很少。
明确地为测试准备测试数据(通过 fixtures 或在测试或设置中手动)以便它们独立于数据库的当前状态
明确使用所需的数据库。
运行 使用
--keepdb
选项进行测试(即./manage.py test --keepdb
,它将使用现有数据库并且不会在测试 运行s 后销毁它)并设置相同的 test database name in app settings as working database(在这种情况下,它不会为测试数据库附加test_
前缀)既然不想用
django.TestCase
,那干脆不用?用unittest.TestCase
替换它们,它不会创建测试数据库