尝试以扩展 VS Code 中的代理模式!

Visual Studio Code 中的 Python 测试

Python 扩展基于 VS Code 内置的测试功能,为 Python 内置的 unittest 框架和 pytest 提供测试发现、测试覆盖率以及运行和调试测试的功能。

配置测试

安装 Python 扩展并在编辑器中打开 Python 文件时,VS Code 活动栏上会显示一个测试烧杯图标,代表“测试资源管理器”视图。如果未启用测试框架,打开“测试资源管理器”会显示“配置 Python 测试”按钮。选择“配置 Python 测试”会提示您选择一个测试框架以及包含测试的文件夹。如果您使用 unittest,您还需要选择用于识别测试文件的文件 glob 模式。

注意

文件 glob 模式是一种定义好的字符串模式,它根据通配符匹配文件或文件夹名称,以包含或不包含文件。

Configure Python Tests button displayed in the Test Explorer when tests haven't been configured.

您可以随时通过命令面板中的“Python: 配置测试”命令,或在“设置编辑器”或 settings.json 文件中设置 python.testing.unittestEnabledpython.testing.pytestEnabled 来配置测试,如 VS Code 设置文档中所述。每个框架还具有特定的配置设置,如测试配置设置下对其文件夹和模式的描述。

如果您启用了 pytest 并且它当前未安装在激活的环境中,Python 扩展会尝试在后台安装它。此外,如果两个框架都启用,Python 扩展将只运行 pytest

注意

Python 扩展支持的 pytest 最低版本是 7.0.0。

测试发现

默认情况下,一旦您启用框架,Python 扩展就会尝试发现测试。您可以随时使用“命令面板”中的“测试: 刷新测试”命令触发测试发现。

提示

python.testing.autoTestDiscoverOnSaveEnabled 默认设置为 true,这意味着每当您在工作区中添加、删除或更新任何 Python 文件时,都会自动进行测试发现。要禁用此功能,请将其值设置为 false,这可以在“设置编辑器”或 settings.json 文件中完成,如 VS Code 设置文档中所述。您需要重新加载窗口才能使此设置生效。要更精细地控制自动测试发现中包含的文件,请调整 python.testing.autoTestDiscoverOnSavePattern 设置,其默认值为 **/*.py

测试发现会应用当前框架的发现模式(可以使用测试配置设置进行自定义)。默认行为如下:

  • python.testing.unittestArgs:在顶级项目文件夹中查找名称中包含“test”的任何 Python (.py) 文件。所有测试文件必须是可导入的模块或包。您可以使用 -p 配置设置自定义文件匹配模式,并使用 -t 设置自定义文件夹。

  • python.testing.pytestArgs:查找名称以“test_”开头或以“_test”结尾的任何 Python (.py) 文件,这些文件位于当前文件夹及其所有子文件夹中的任何位置。

提示

有时放置在子文件夹中的测试无法被发现,因为这些测试文件无法导入。要使它们可导入,请在该文件夹中创建一个名为 __init__.py 的空文件。

如果测试发现成功,您将在“测试资源管理器”中看到列出的测试。

The VS Code Test Explorer for Python tests

当直接从“测试资源管理器”触发测试发现时,您还可以取消正在进行的测试发现调用。使用“取消”按钮,它在发现期间会替换“刷新”按钮。

Cancel test discovery button in the Test Explorer.

如果发现失败(例如,测试框架未安装或您的测试文件中有语法错误),您将在“测试资源管理器”中看到错误消息,其中包含指向日志的链接。您可以检查“Python”输出面板以查看完整的错误消息(使用“查看”>“输出”菜单命令显示“输出”面板,然后从右侧的下拉列表中选择“Python”)。

Discovery failure error messaged displayed in the Test Explorer

运行测试

您可以通过以下任一操作运行测试:

  • 打开测试文件后,选择测试定义行旁边的装订线中显示的绿色运行图标,如上一节所示。此命令仅运行该方法。

    Run test icon displayed on the gutter when the test file is open in the editor

  • 从“命令面板”中,运行以下任一命令:

    • 测试: 运行所有测试 - 运行所有已发现的测试。
    • 测试: 运行当前文件中的测试 - 运行编辑器中打开的文件中的所有测试。
    • 测试: 运行光标处的测试 - 仅运行编辑器中光标下的测试方法。
  • 从“测试资源管理器”中:

    • 要运行所有已发现的测试,请选择“测试资源管理器”顶部的播放按钮。

      Running all tests through Test Explorer

    • 要运行特定组的测试或单个测试,请选择文件、类或测试,然后选择该项目右侧的播放按钮。

      Running tests at specific scopes through Test Explorer

    • 您还可以通过“测试资源管理器”运行选定的测试。为此,请在您希望运行的测试上Ctrl+单击(或在 macOS 上Cmd+单击),然后右键单击其中一个并选择“运行测试”。

测试运行后,VS Code 会直接在编辑器中以装订线装饰的形式显示结果。失败的测试也会在编辑器中高亮显示,并带有“速览视图”来显示测试运行错误消息和所有测试运行的历史记录。您可以按 Escape 键关闭该视图,也可以通过打开用户设置(“命令面板”中的“首选项: 打开设置 (UI)”命令)并将“测试: 自动打开速览视图”设置的值更改为 never 来禁用它。

在“测试资源管理器”中,会显示单个测试以及包含这些测试的任何类和文件的结果。如果该文件夹中的任何测试未通过,文件夹将显示一个失败图标。

Test results on a unittest class and in Test Explorer

VS Code 还在“测试结果”面板中显示测试结果。

Test results in the Test Results panel

运行带覆盖率的测试

要运行带有覆盖率的测试,请在“测试资源管理器”中选择覆盖率运行图标,或从您通常触发测试运行的任何菜单中选择“运行带覆盖率”选项。如果您使用 pytest,Python 扩展会使用 pytest-cov 插件运行覆盖率;如果是 unittest,则使用 coverage.py

注意

在运行带有覆盖率的测试之前,请确保为您的项目安装正确的测试覆盖率包。分支覆盖率仅在 coverage 版本 >= 7.7 上受支持。

覆盖率运行完成后,编辑器中会高亮显示行以指示行级覆盖率。“测试覆盖率”结果会在“测试资源管理器”中显示为“测试覆盖率”子选项卡,您也可以通过“命令面板”中的“测试: 聚焦于测试覆盖率视图”命令导航到该选项卡(⇧⌘P (Windows, Linux Ctrl+Shift+P))。在此面板上,您可以查看工作区中每个文件和文件夹的行覆盖率指标,如果相关,还可以查看分支覆盖率。

Gif showing running Python tests with coverage.

为了在使用 pytest 时更精细地控制覆盖率运行,您可以编辑 python.testing.pytestArgs 设置以包含您的具体配置。当 python.testing.pytestArgs 中存在 pytest 参数 --cov 时,Python 扩展将不会对覆盖率参数进行额外修改,以允许您的自定义生效。如果未找到 --cov 参数,扩展将在运行前向 pytest 参数中添加 --cov=.,以在工作区根目录启用覆盖率。

有关测试覆盖率的更多信息,请访问 VS Code 的测试覆盖率文档

调试测试

要调试测试,请右键单击函数定义旁边的装订线装饰并选择“调试测试”,或在“测试资源管理器”中选择该测试旁边的“调试测试”图标。

Debug Test icon in the Test Explorer

注意

运行或调试测试不会自动保存测试文件。在运行测试之前,请务必保存对测试的更改,否则您可能会因结果仍然反映文件的旧版本而感到困惑!

您可以使用“命令面板”中的以下命令来调试测试:

  • 测试: 调试所有测试 - 启动工作区中所有测试的调试器。
  • 测试: 调试当前文件中的测试 - 启动编辑器中打开的文件中定义的测试的调试器。
  • 测试: 调试光标处的测试 - 仅启动编辑器中光标聚焦的方法的调试器。您还可以使用“测试资源管理器”中的“调试测试”图标来启动所选范围内的所有测试和所有已发现测试的调试器。

您还可以通过将 settings.json 文件中的 testing.defaultGutterClickAction 设置值更改为 debug,从而将点击装订线装饰的默认行为改为调试测试而不是运行测试。

调试器对测试和其他 Python 代码的工作方式相同,包括断点、变量检查等。要自定义测试调试设置,您可以通过将 "purpose": ["debug-test"] 添加到您的配置中,在工作区的 .vscode 文件夹中的 launch.jsonsettings.json 文件中指定测试调试配置。此配置将在您运行“测试: 调试所有测试”、“测试: 调试当前文件中的测试”和“测试: 调试光标处的测试”命令时使用。

例如,launch.json 文件中的以下配置禁用了调试测试时的 justMyCode 设置:

{
  "name": "Python: Debug Tests",
  "type": "debugpy",
  "request": "launch",
  "program": "${file}",
  "purpose": ["debug-test"],
  "console": "integratedTerminal",
  "justMyCode": false
}

如果您有多个包含 "purpose": ["debug-test"] 的配置条目,将使用第一个定义,因为我们目前不支持此请求类型的多个定义。

有关调试的更多信息或了解其在 VS Code 中的工作原理,请阅读Python 调试配置和通用 VS Code 调试文章。

并行运行测试

通过 pytest-xdist 包可以支持使用 pytest 并行运行测试。请访问其文档,以获取有关如何使用 pytest-xdist 的更多信息。

当启用 xdist 且参数中未指定工作进程数时,Python 扩展会根据“测试资源管理器”中选择的测试数量自动优化工作进程数。

Django 单元测试

Python 扩展还支持发现和运行 Django 单元测试!只需几个额外的设置步骤即可发现您的 Django 测试:

  1. 在您的 settings.json 文件中设置 "python.testing.unittestEnabled": true,
  2. 添加 MANAGE_PY_PATH 作为环境变量
    1. 在项目根目录创建 .env 文件。
    2. MANAGE_PY_PATH='<path-to-manage.py>' 添加到 .env 文件中,并将 <path-to-manage.py> 替换为您的应用程序的 manage.py 文件的路径。

      提示:您可以通过右键单击“资源管理器”视图中的文件并选择“复制路径”来复制路径。

  3. 根据需要在 settings.json 文件中的 "python.testing.unittestArgs": [] 中添加 Django 测试参数,并删除任何与 Django 不兼容的参数。
注意

默认情况下,Python 扩展会在项目根目录查找并加载 .env 文件。如果您的 .env 文件不在项目根目录,或者您正在使用 VS Code 变量替换,请将 "python.envFile": "${workspaceFolder}/<path-to-.env>" 添加到您的 settings.json 文件中。这使得 Python 扩展在运行和发现测试时能够从该文件中加载环境变量。获取有关 Python 环境变量的更多信息。

导航到“测试”视图,然后选择“刷新测试”按钮以显示您的 Django 测试!

故障排除

如果您的 Django 单元测试未在“测试”视图中显示,请尝试以下故障排除步骤:

  • 在“Python”输出面板中查找错误消息。它们可能会提示您为什么未发现测试。
  • 尝试在终端中运行 Django 测试。然后将相同的命令“转换”为 VS Code 设置。例如,如果您在终端中运行 python manage.py test --arg,则应将 MANAGE_PY_PATH='./manage.py' 添加到 .env 文件中,并在 VS Code 设置中设置 "python.testing.unittestArgs": [--arg]。或者,您也可以在“Python”输出面板中找到由 Python 扩展运行的命令。
  • 如果最初使用了相对路径,请在设置 MANAGE_PY_PATH 环境变量时使用 manage.py 文件的绝对路径。

测试命令

以下是 VS Code 中使用 Python 扩展进行测试的所有受支持命令。这些命令都可以在“命令面板”中找到:

命令名称 描述
Python: 配置测试 配置要与 Python 扩展一起使用的测试框架。
测试: 清除所有结果 清除所有测试状态,因为 UI 会在会话之间保留测试结果。
测试: 调试所有测试 调试所有已发现的测试。与 2021.9 版本之前的“Python: 调试所有测试”等效。
测试: 调试失败的测试 调试最近一次测试运行中失败的测试。
测试: 调试上次运行 调试最近一次测试运行中执行的测试。
测试: 调试光标处的测试 调试编辑器中光标聚焦的测试方法。与 2021.9 版本之前的“Python: 调试测试方法...”类似。
测试: 调试当前文件中的测试 调试编辑器中当前聚焦的文件中的测试。
测试: 转到下一个测试失败 如果错误速览视图已打开,则打开并移动到资源管理器中下一个失败测试的速览视图。
测试: 转到上一个测试失败 如果错误速览视图已打开,则打开并移动到资源管理器中上一个失败测试的速览视图。
测试: 速览输出 打开失败测试方法的错误速览视图。
测试: 刷新测试 执行测试发现并更新“测试资源管理器”以反映任何测试更改、添加或删除。与 2021.9 版本之前的“Python: 发现测试”类似。
测试: 重新运行失败的测试 运行最近一次测试运行中失败的测试。与 2021.9 版本之前的“Python: 运行失败的测试”类似。
测试: 重新运行上次运行 调试最近一次测试运行中执行的测试。
测试: 运行所有测试 运行所有已发现的测试。与 2021.9 版本之前的“Python: 运行所有测试”等效。
测试: 运行所有带覆盖率的测试 运行所有已发现的测试,并计算您的代码有多少被测试覆盖。
测试: 运行光标处的测试 运行编辑器中光标聚焦的测试方法。与 2021.9 版本之前的“Python: 运行测试方法...”类似。
测试: 运行当前文件中的测试 运行编辑器中当前聚焦的文件中的测试。与 2021.9 版本之前的“Python: 运行当前测试文件”等效。
测试: 显示输出 打开包含所有测试运行详细信息的输出。与 2021.9 版本之前的“Python: 显示测试输出”类似。
测试: 聚焦于测试资源管理器视图 打开“测试资源管理器”视图。与 2021.9 版本之前的“测试: 聚焦于 Python 视图”类似。
测试: 停止刷新测试 取消测试发现。

测试配置设置

使用 Python 进行测试的行为由 VS Code 提供的通用 UI 设置以及特定于 Python 和您启用的任何框架的设置驱动。

通用 UI 设置

影响测试功能 UI 的设置由 VS Code 本身提供,当您搜索“Testing”时,可以在 VS Code 设置编辑器中找到它们。

通用 Python 设置

设置
(python.testing.)
默认值 描述
autoTestDiscoverOnSaveEnabled true 指定在保存测试文件时是否启用或禁用自动运行测试发现。更改此设置后,您可能需要重新加载窗口才能使其生效。
cwd null 指定测试的可选工作目录。此设置的存在会动态调整 pytest 的 --rootdir 参数。
autoTestDiscoverOnSavePattern **/*.py 指定一个 glob 模式,该模式决定当 autoTestDiscoverOnSaveEnabledtrue 时,哪些文件更改会触发自动测试发现。
debugPort 3000 用于调试 unittest 测试的端口号。
promptToConfigure true 指定如果发现潜在测试,VS Code 是否提示配置测试框架。

unittest 配置设置

Unittest 设置
(python.testing.)
默认值 描述
unittestEnabled false 指定是否启用 unittest 作为测试框架。pytest 的相应设置应禁用。
unittestArgs ["-v", "-s", ".", "-p", "*test*.py"] 传递给 unittest 的参数,其中每个由空格分隔的元素都是列表中的一个单独项。有关默认值的描述,请参见下文。

unittest 的默认参数如下:

  • -v 设置默认详细程度。删除此参数以获得更简单的输出。
  • -s . 指定发现测试的起始目录。如果您的测试位于“test”文件夹中,请将参数更改为 -s test(即参数数组中的 "-s", "test")。
  • -p *test*.py 是用于查找测试的发现模式。在这种情况下,它是任何包含单词“test”的 .py 文件。如果您以不同的方式命名测试文件,例如在每个文件名后附加“_test”,则在数组的相应参数中使用类似 *_test.py 的模式。

要在第一次失败时停止测试运行,请将快速失败选项 "-f" 添加到参数数组中。

有关可用选项的完整集合,请参阅 unittest 命令行界面

pytest 配置设置

pytest 设置
(python.testing.)
默认值 描述
pytestEnabled false 指定是否启用 pytest 作为测试框架。unittest 的相应设置应禁用。
pytestPath "pytest" pytest 的路径。如果 pytest 位于当前环境之外,请使用完整路径。
pytestArgs [] 传递给 pytest 的参数,其中每个由空格分隔的元素都是列表中的一个单独项。请参阅 pytest 命令行选项

pytest 的默认参数如下:

  • rootdir 会根据工作区中是否存在 python.testing.cwd 设置进行动态调整。

您还可以使用 pytest.ini 文件配置 pytest,如 pytest 配置中所述。

注意

如果安装了 pytest-cov 覆盖率模块,VS Code 在调试时不会在断点处停止,因为 pytest-cov 使用相同的技术来访问正在运行的源代码。为了防止此行为,在调试测试时,请在 pytestArgs 中包含 --no-cov,例如通过将 "env": {"PYTEST_ADDOPTS": "--no-cov"} 添加到您的调试配置中。(请参阅上面的调试测试了解如何设置该启动配置。)(有关更多信息,请参阅 pytest-cov 文档中的调试器和 PyCharm。)

IntelliSense 设置

IntelliSense 设置
(python.analysis.)
默认值 描述
inlayHints.pytestParameters false 是否显示 pytest fixture 参数类型的内联提示。可接受的值为 truefalse

另请参阅

  • Python 环境 - 控制用于编辑和调试的 Python 解释器。
  • 设置参考 - 探索 VS Code 中所有与 Python 相关的设置。