无法在 Visual Studio Code 中调试 Django 单元测试

Jer*_* K. 10 python django debugging unit-testing visual-studio-code

我希望能够从 Visual Studio Code 中运行和调试 Django 项目的单元测试。我是一名经验丰富的开发人员,但对 Django 和 Visual Studio Code 都相当陌生。

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

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

迄今为止最好的解决方案

我发现的最佳解决方案是Visual Studio Code 下的 Django 应用单元测试问题。它涉及将这四行放入一个 __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()
Run Code Online (Sandbox Code Playgroud)

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

尝试过的其他解决方案

运行 django 测试时如何修复“TypeError:'ConnectionHandler' 类型的参数不可迭代”中的 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 在 VSC 中运行 Django 单元测试:https ://technowhisp.com/django-unit-testing-in-vscode/ 。但即使在仔细遵循他的步骤之后,我也无法让 pytest 发现 Visual Studio Code 中的单元测试。

Visual Studio 2017 或 2019中的Django 单元测试中的 StackOverflow 问题没有答案。提问者作为部分解决方案呈现的代码既丑陋又臃肿。该问题被标记为可能与Visual Studio 2017 或 2019 中Django 单元测试重复,但该问题也没有答案。StackOverflow 上的其他问题与 Django 甚至 Python 无关。

我的设置

这个问题的其余部分描述了我的环境以及我遇到的问题的确切性质。我正在使用一个现有的应用程序,但已经成功地在两个教程项目中重现了这个问题——Django 团队在他们的“编写你的第一个 Django 应用程序”在线教程中提供的一个,网址https://docs.djangoproject.com/en /3.0/intro/,以及 Visual Studio Code 团队在https://code.visualstudio.com/docs/python/tutorial-django提供的第二个教程 。在结构上,这两个项目的区别在于,第二个项目在项目根目录下有 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
Run Code Online (Sandbox Code Playgroud)

这是我的 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
}
Run Code Online (Sandbox Code Playgroud)

该文件显示了在“-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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

在 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
Run Code Online (Sandbox Code Playgroud)

命令行中的 ConnectionHandler 错误

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

在此先感谢你们能给我的任何帮助。

小智 6

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

\n\n

如果pytest这是您的一个选项,您必须安装pytestpytest-django

\n\n
pip install pytest pytest-django\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. 使用以下内容在同一级别的文件中创建pytest配置(例如: ) 。pytest.inimanage.py

    \n\n
    [pytest]\nDJANGO_SETTINGS_MODULE=mysite.settings\npython_files=test*.py\n
    Run Code Online (Sandbox Code Playgroud)\n\n

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

  2. \n
  3. 更新setting.json配置文件:

    \n\n
    {\n    "python.pythonPath": "venv/bin/python",\n    "python.testing.pytestArgs": [\n        "mysite",\n        "-s",\n        "-vv"\n    ],\n    "python.testing.pytestEnabled": true,\n    "python.testing.nosetestsEnabled": false,\n    "python.testing.unittestEnabled": false\n}\n
    Run Code Online (Sandbox Code Playgroud)
  4. \n
\n\n

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

\n\n
PYTHONPATH=mysite/\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
.  <-- vs code root\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 .env  <-- file created with the PYTHONPATH entry\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 mysite\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pytest.ini  <-- pytest configuration\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 db.sqlite3\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 manage.py\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mysite\n    \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n    \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 asgi.py\n    \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 settings.py\n    \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 urls.py\n    \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 wsgi.py\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 polls\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 admin.py\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 apps.py\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 migrations\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 models.py\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mydate.py\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 tests.py\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 urls.py\n        \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 views.py\n
Run Code Online (Sandbox Code Playgroud)\n