【问题标题】:Can't debug Django unit tests within Visual Studio Code无法在 Visual Studio Code 中调试 Django 单元测试
【发布时间】:2020-06-09 04:33:14
【问题描述】:

我希望能够在 Visual Studio Code 中运行和调试 Django 项目的单元测试。我是一位经验丰富的开发人员,但对 Django 和 Visual Studio Code 来说都是新手。

问题的症结在于测试在 Visual Studio Code 中是不可发现的,或者如果它们是可发现的,则在运行它们时会出现 ConnectionHandler 异常。我在下面提供了这两种情况的详细信息。

对于这个问题的冗长,我深表歉意,但我认为我应该列出我尝试失败的问题的许多解决方案。我还认为将它们全部放在一个地方可能会很有用,而不是将它们分散在 StackOverflow 和 Internet 的其他部分。

迄今为止最好的解决方案

我找到的最佳解决方案是Problem with Django app unit tests under Visual Studio Code。它涉及将这四行放入 __init__.py 文件中:

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_app_project.settings")

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

这在我的简单教程项目中有效,如下所述,但在实际应用程序中,一些测试失败。看起来好像 Django 没有独立于其他测试运行数据库模型,或者没有调用测试的 tearDown() 方法。此外,不清楚将这些行放在哪个 __init__.py 文件中。最后,此解决方案会导致从命令行运行单元测试时失败。

尝试过的其他解决方案

How to fix "TypeError: argument of type 'ConnectionHandler' is not iterable" when running a django test? 的 StackOverflow 问题似乎与我的问题的 ConnectionHandler 方面相似,但没有人在那里提出解决方案。

我找到了一个可以解决这些问题的 Visual Studio Code 扩展:Django Test Runner (https://marketplace.visualstudio.com/items?itemName=Pachwenko.django-test-runner)。它目前在https://github.com/Pachwenko/VSCode-Django-Test-Runner/issues/5 有一个问题,描述了我在扩展程序中遇到的问题。

这篇博客说你可以使用 pytest:https://technowhisp.com/django-unit-testing-in-vscode/ 在 VSC 中运行 Django 单元测试。但即使仔细按照他的步骤进行操作,我也无法通过 pytest 发现 Visual Studio Code 中的单元测试。

Django Unit Testing in Visual Studio 2017 or 2019: 的 StackOverflow 问题没有答案。提问者作为部分解决方案提供的代码既丑陋又臃肿。该问题被标记为可能与 Django Unit Testing in Visual Studio 2017 or 2019: 重复,但该问题也没有答案。 StackOverflow 上的其他问题与 Django 甚至 Python 无关。

我的设置

这个问题的其余部分描述了我的环境以及我遇到的问题的确切性质。我正在使用现有的应用程序,但已设法在两个教程项目中重现该问题——一个由 Django 团队在他们的“编写你的第一个 Django 应用程序”在线教程https://docs.djangoproject.com/en/3.0/intro/ 中提供,第二个教程由https://code.visualstudio.com/docs/python/tutorial-django 的 Visual Studio Code 团队。在结构上,这两个项目的区别在于,第二个项目的 manage.py 脚本与项目根目录位于同一目录,而第一个项目的脚本位于项目根目录的下一个目录。

我可以毫无问题地从命令行运行测试。我希望能够从 Visual Studio Code 中运行它们,因为有时我想通过调试器运行它们。

我正在使用 python 3.7、Django 3.0.3、Visual Studio Code 1.42.1、Windows 10、Linux 的 Windows 子系统和 unittest 框架。

至于我的项目,我将描述第一个教程的设置,因为这与我的实际项目的设置方式最相似。根目录称为 mysite。 tree 命令的清理输出给出了以下内容:

.
└── mysite
    ├── db.sqlite3
    ├── manage.py
    ├── mysite
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── polls
        ├── __init__.py
        ├── admin.py
        ├── apps.py
        ├── migrations
        ├── models.py
        ├── mydate.py
        ├── tests.py
        ├── urls.py
        └── views.py

这是我的 VSC settings.json 文件:

{
    "python.pythonPath": "venv/bin/python",
    "python.testing.unittestArgs": [
        "-v",
        "-s",
        // "/full/path/to/mysite",
        "./mysite",
        // "mysite",
        "-p",
        "test*.py"
    ],
    "python.testing.pytestEnabled": false,
    "python.testing.nosetestsEnabled": false,
    "python.testing.unittestEnabled": true
}

该文件显示在“-s”参数后注释掉的两行。无论我将这三行中的哪一行用于路径,我都会得到相同的行为。

VSC 中的 ConnectionHandler 错误

在 Visual Studio Code 中,我的 polls/tests.py 文件如下所示:

如您所见,“运行测试”和“调试测试”按钮表示测试是可发现的。使用 unittest 导入,测试可以在 VSC 中正确运行,但是使用 django.test 导入我得到一个 ConnectionHandler 错误,并显示以下消息堆栈:

======================================================================
ERROR: setUpClass (polls.tests.TestDjango)----------------------------------------------------------------------
Traceback (most recent call last):  
File "/home/jkurlandski/workspace/randd/djangoprojs/mysite/venv/lib/python3.7/site-packages/django/test/testcases.py", line 1123, in setUpClass    super().setUpClass()  
File "/home/jkurlandski/workspace/randd/djangoprojs/mysite/venv/lib/python3.7/site-packages/django/test/testcases.py", line 197, in setUpClass    cls._add_databases_failures()  
File "/home/jkurlandski/workspace/randd/djangoprojs/mysite/venv/lib/python3.7/site-packages/django/test/testcases.py", line 218, in _add_databases_failures    cls.databases = cls._validate_databases()  File "/home/jkurlandski/workspace/randd/djangoprojs/mysite/venv/lib/python3.7/site-packages/django/test/testcases.py", line 204, in _validate_databases    if alias not in connections:
TypeError: argument of type 'ConnectionHandler' is not iterable
----------------------------------------------------------------------
Ran 0 tests in 0.001s

VSC 中的导入问题

在 mysite/mysite/polls/models.py 中,我创建了与上面引用的 Django 教程中描述的相同的问题和选择模型。但是,当我尝试导入它们时,无法再发现测试 - VSC 中的“运行”和“调试”按钮消失了,并且我收到一条消息说它们无法发现。

from django.test import TestCase
# from unittest import TestCase

# not discoverable:
# from .models import Choice
# not discoverable: 
# from polls.models import Choice

在 VSC 中,使用 from polls.models import Choice 会产生“未解决的导入 'polls.models' 警告,并导致导入语句变为黄色下划线。from .models import Choice 导入不会导致警告。由于测试未可发现我无法在 VSC 中运行或调试它。(但请注意,正如我所说,从命令行可以正确运行测试。)

作为一个实验,我在 polls 中创建了文件 mydate.py,与 models.py 相同的目录,包含一个名为 getNow() 的函数。我可以将此文件导入到 tests.py 中而不会丢失测试可发现性,但运行测试会导致上述相同的 ConnectionHandler 错误。

from django.test import TestCase
# from unittest import TestCase

# discoverable, but TypeError: argument of type 'ConnectionHandler' is not iterable: 
from polls.mydate import getNow
# discoverable, but TypeError: argument of type 'ConnectionHandler' is not iterable: 
# from .mydate import getNow

来自命令行的 ConnectionHandler 错误

正如我所说,我可以使用python manage.py test 从命令行运行单元测试。但是,我可以通过从 manage.py 目录运行 python -m unittest 来复制 ConnectionHandler 错误。

提前感谢你们能给我的任何帮助。

【问题讨论】:

标签: python django unit-testing debugging visual-studio-code


【解决方案1】:

您需要在运行任何测试之前加载 django 配置,因此 __init__.py 文件中的代码。

如果您可以选择pytest,则必须安装pytestpytest-django

pip install pytest pytest-django
  1. manage.py 文件的同一级别创建pytest 配置(例如:pytest.ini),内容如下。

    [pytest]
    DJANGO_SETTINGS_MODULE=mysite.settings
    python_files=test*.py
    

    配置DJANGO_SETTINGS_MODULE是项目设置所需的导入(settings.py文件)。默认情况下,当您使用 python manage.py startapp app_name 时,会为每个应用程序创建文件 tests.py,但此文件与默认的 pytest 文件模式不匹配,因此您必须添加 python_files 选项,如果您想使用默认文件名。

  2. 更新setting.json 配置文件:

    {
        "python.pythonPath": "venv/bin/python",
        "python.testing.pytestArgs": [
            "mysite",
            "-s",
            "-vv"
        ],
        "python.testing.pytestEnabled": true,
        "python.testing.nosetestsEnabled": false,
        "python.testing.unittestEnabled": false
    }
    

关于错误unresolved import 'polls.models',你需要在VSCode上配置Python扩展,在你的项目根目录下创建一个.env文件PYTHONPATH=source_code_folder(更多信息VS Code Python Environment):

PYTHONPATH=mysite/

最后,你的项目结构应该是

.  <-- vs code root
├── .env  <-- file created with the PYTHONPATH entry
└── mysite
    ├── pytest.ini  <-- pytest configuration
    ├── db.sqlite3
    ├── manage.py
    ├── mysite
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── polls
        ├── __init__.py
        ├── admin.py
        ├── apps.py
        ├── migrations
        ├── models.py
        ├── mydate.py
        ├── tests.py
        ├── urls.py
        └── views.py

【讨论】:

  • Motakjuq 的回答解决了我的问题。我将在一个更复杂的项目上尝试他/她的建议并在这里报告
  • Motakjuq 的答案也适用于更复杂的现实世界项目。 Motakjuq 回答的关键要素是:1. pip install pytest pytest-django 2. 创建 pytest.ini 文件。 3. 更新setting.json 配置文件。 .env 文件有助于解决 VSC 警告,但不是必需的。对__init__.py 文件的更改是不必要的。完成配置后,您应该能够成功: 从 Visual Studio Code 中运行所有单元测试;从 VSC 中调试任何单元测试;并使用 python manage.py test 从命令行运行所有单元测试。
猜你喜欢
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 2023-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
相关资源
最近更新 更多