Visual Studio Code 中的 Python 测试
Python 扩展基于 VS Code 内置的测试功能,为 Python 内置的 unittest 框架和 pytest 提供测试发现、测试覆盖率以及运行和调试测试的功能。
配置测试
安装 Python 扩展并在编辑器中打开 Python 文件时,VS Code 活动栏上会显示一个测试烧杯图标,代表“测试资源管理器”视图。如果未启用测试框架,打开“测试资源管理器”会显示“配置 Python 测试”按钮。选择“配置 Python 测试”会提示您选择一个测试框架以及包含测试的文件夹。如果您使用 unittest,您还需要选择用于识别测试文件的文件 glob 模式。
文件 glob 模式是一种定义好的字符串模式,它根据通配符匹配文件或文件夹名称,以包含或不包含文件。
您可以随时通过命令面板中的“Python: 配置测试”命令,或在“设置编辑器”或 settings.json
文件中设置 python.testing.unittestEnabled
或 python.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
的空文件。
如果测试发现成功,您将在“测试资源管理器”中看到列出的测试。
当直接从“测试资源管理器”触发测试发现时,您还可以取消正在进行的测试发现调用。使用“取消”按钮,它在发现期间会替换“刷新”按钮。
如果发现失败(例如,测试框架未安装或您的测试文件中有语法错误),您将在“测试资源管理器”中看到错误消息,其中包含指向日志的链接。您可以检查“Python”输出面板以查看完整的错误消息(使用“查看”>“输出”菜单命令显示“输出”面板,然后从右侧的下拉列表中选择“Python”)。
运行测试
您可以通过以下任一操作运行测试:
-
打开测试文件后,选择测试定义行旁边的装订线中显示的绿色运行图标,如上一节所示。此命令仅运行该方法。
-
从“命令面板”中,运行以下任一命令:
- 测试: 运行所有测试 - 运行所有已发现的测试。
- 测试: 运行当前文件中的测试 - 运行编辑器中打开的文件中的所有测试。
- 测试: 运行光标处的测试 - 仅运行编辑器中光标下的测试方法。
-
从“测试资源管理器”中:
-
要运行所有已发现的测试,请选择“测试资源管理器”顶部的播放按钮。
-
要运行特定组的测试或单个测试,请选择文件、类或测试,然后选择该项目右侧的播放按钮。
-
您还可以通过“测试资源管理器”运行选定的测试。为此,请在您希望运行的测试上Ctrl+单击(或在 macOS 上Cmd+单击),然后右键单击其中一个并选择“运行测试”。
-
测试运行后,VS Code 会直接在编辑器中以装订线装饰的形式显示结果。失败的测试也会在编辑器中高亮显示,并带有“速览视图”来显示测试运行错误消息和所有测试运行的历史记录。您可以按 Escape 键关闭该视图,也可以通过打开用户设置(“命令面板”中的“首选项: 打开设置 (UI)”命令)并将“测试: 自动打开速览视图”设置的值更改为 never
来禁用它。
在“测试资源管理器”中,会显示单个测试以及包含这些测试的任何类和文件的结果。如果该文件夹中的任何测试未通过,文件夹将显示一个失败图标。
VS Code 还在“测试结果”面板中显示测试结果。
运行带覆盖率的测试
要运行带有覆盖率的测试,请在“测试资源管理器”中选择覆盖率运行图标,或从您通常触发测试运行的任何菜单中选择“运行带覆盖率”选项。如果您使用 pytest,Python 扩展会使用 pytest-cov
插件运行覆盖率;如果是 unittest,则使用 coverage.py
。
在运行带有覆盖率的测试之前,请确保为您的项目安装正确的测试覆盖率包。分支覆盖率仅在 coverage 版本 >= 7.7 上受支持。
覆盖率运行完成后,编辑器中会高亮显示行以指示行级覆盖率。“测试覆盖率”结果会在“测试资源管理器”中显示为“测试覆盖率”子选项卡,您也可以通过“命令面板”中的“测试: 聚焦于测试覆盖率视图”命令导航到该选项卡(⇧⌘P (Windows, Linux Ctrl+Shift+P))。在此面板上,您可以查看工作区中每个文件和文件夹的行覆盖率指标,如果相关,还可以查看分支覆盖率。
为了在使用 pytest 时更精细地控制覆盖率运行,您可以编辑 python.testing.pytestArgs
设置以包含您的具体配置。当 python.testing.pytestArgs
中存在 pytest 参数 --cov
时,Python 扩展将不会对覆盖率参数进行额外修改,以允许您的自定义生效。如果未找到 --cov
参数,扩展将在运行前向 pytest 参数中添加 --cov=.
,以在工作区根目录启用覆盖率。
有关测试覆盖率的更多信息,请访问 VS Code 的测试覆盖率文档。
调试测试
要调试测试,请右键单击函数定义旁边的装订线装饰并选择“调试测试”,或在“测试资源管理器”中选择该测试旁边的“调试测试”图标。
运行或调试测试不会自动保存测试文件。在运行测试之前,请务必保存对测试的更改,否则您可能会因结果仍然反映文件的旧版本而感到困惑!
您可以使用“命令面板”中的以下命令来调试测试:
- 测试: 调试所有测试 - 启动工作区中所有测试的调试器。
- 测试: 调试当前文件中的测试 - 启动编辑器中打开的文件中定义的测试的调试器。
- 测试: 调试光标处的测试 - 仅启动编辑器中光标聚焦的方法的调试器。您还可以使用“测试资源管理器”中的“调试测试”图标来启动所选范围内的所有测试和所有已发现测试的调试器。
您还可以通过将 settings.json
文件中的 testing.defaultGutterClickAction
设置值更改为 debug
,从而将点击装订线装饰的默认行为改为调试测试而不是运行测试。
调试器对测试和其他 Python 代码的工作方式相同,包括断点、变量检查等。要自定义测试调试设置,您可以通过将 "purpose": ["debug-test"]
添加到您的配置中,在工作区的 .vscode
文件夹中的 launch.json
或 settings.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 测试:
- 在您的
settings.json
文件中设置"python.testing.unittestEnabled": true,
。 - 添加
MANAGE_PY_PATH
作为环境变量- 在项目根目录创建
.env
文件。 - 将
MANAGE_PY_PATH='<path-to-manage.py>'
添加到.env
文件中,并将<path-to-manage.py>
替换为您的应用程序的manage.py
文件的路径。提示:您可以通过右键单击“资源管理器”视图中的文件并选择“复制路径”来复制路径。
- 在项目根目录创建
- 根据需要在
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 模式,该模式决定当 autoTestDiscoverOnSaveEnabled 为 true 时,哪些文件更改会触发自动测试发现。 |
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 参数类型的内联提示。可接受的值为 true 或 false 。 |