gpt4 book ai didi

python - Django 测试运行器不尊重 unittest.TestCase?

转载 作者:行者123 更新时间:2023-12-04 03:59:15 26 4
gpt4 key购买 nike

对于我的一个功能测试,我决定使用 unittest.TestCase 而不是 Django 测试类,因为在清理测试时直接访问我的本地开发数据库很方便测试自己。

像我预期的那样单独运行测试:

$ 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 将所有测试包装在有关测试运行器的任何内容中,从而阻止我的测试直接访问 Object 吗?

最佳答案

先做一点解释。

默认情况下,当您运行 ./manage.py test 时,django test-runner 会执行几个步骤,其中涉及创建测试数据库(每个数据库名称都带有 test_ 前缀,从 app settings 开始), 运行迁移并销毁测试数据库(关于运行器步骤的更多细节可以找到 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 看到它(原始 unittest.TestCase 没有 databases 属性,当 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'...

正如您提到的,测试失败是因为没有为它们准备好的对象。


解决方案

在这一点上,我看到解决这个问题的选项很少。

  1. 明确地为测试准备测试数据(通过 fixtures 或在测试或设置中手动),以便它们独立于数据库的当前状态

  2. 明确使用所需的数据库。

    使用--keepdb 选项运行测试(即./manage.py test --keepdb,它将使用现有的数据库并且不会在测试运行后销毁它) 并在应用程序设置中将相同的 test database name 设置为 working database(在这种情况下,它不会为测试数据库附加 test_ 前缀)

  3. 既然你不想使用django.TestCase,那么根本就不要使用它们?将它们替换为 unittest.TestCase 并且它不会创建测试数据库

关于python - Django 测试运行器不尊重 unittest.TestCase?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63347933/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com