在 Visual Studio Code 中进行 Python 测试
Python 扩展构建于 VS Code 内置的测试功能之上,为 Python 的内置 unittest 框架和 pytest 提供了测试发现、测试覆盖率以及运行和调试测试的功能。
配置测试
当安装了 Python 扩展并且在编辑器中打开了 Python 文件时,VS Code 的活动栏上会显示一个测试烧杯图标,代表测试资源管理器视图。如果尚未启用测试框架,打开测试资源管理器会显示一个配置 Python 测试按钮。选择配置 Python 测试会提示您选择一个测试框架和一个包含测试的文件夹。如果您使用 unittest,您还需要选择用于识别测试文件的文件 glob 模式。
文件 glob 模式是一个定义的字符串模式,它根据通配符来匹配文件或文件夹名称,以包含或不包含文件。
可以随时通过命令面板中的Python: Configure Tests(Python: 配置测试)命令来配置测试,或者如 VS Code 设置文档中所述,在设置编辑器或 settings.json
文件中设置 python.testing.unittestEnabled
或 python.testing.pytestEnabled
。每个框架也都有特定的配置设置,详见测试配置设置中关于其文件夹和模式的描述。
如果您启用了 pytest,并且它当前未安装在已激活的环境中,Python 扩展会尝试在后台安装它。此外,如果两个框架都已启用,Python 扩展将只运行 pytest
。
Python 扩展支持的 pytest 最低版本为 7.0.0。
测试发现
默认情况下,一旦您启用了一个框架,Python 扩展就会尝试发现测试。您可以随时使用命令面板中的Test: Refresh Tests(测试: 刷新测试)命令来触发测试发现。
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)。
运行测试
您可以使用以下任何操作来运行测试:
-
打开一个测试文件,选择显示在测试定义行旁边行号槽中的绿色运行图标,如上一节所示。此命令仅运行该方法。
-
通过运行以下任何命令从命令面板执行:
- Test: Run All Tests(测试: 运行所有测试)- 运行所有已发现的测试。
- Test: Run Tests in Current File(测试: 运行当前文件中的测试)- 运行在编辑器中打开的文件中的所有测试。
- Test: Run Test at Cursor(测试: 运行光标处的测试)- 仅运行编辑器中光标下的测试方法。
-
从测试资源管理器:
-
要运行所有已发现的测试,请选择测试资源管理器顶部的播放按钮。
-
要运行特定的测试组或单个测试,请选择文件、类或测试,然后选择该项目右侧的播放按钮。
-
您还可以通过测试资源管理器运行选定的一组测试。为此,请按住 Ctrl+单击(在 macOS 上为 Cmd+单击)您希望运行的测试,右键单击其中一个,然后选择运行测试。
-
测试运行后,VS Code 会以行号槽装饰的形式直接在编辑器中显示结果。失败的测试也会在编辑器中高亮显示,并带有一个速览视图,显示测试运行的错误消息和所有测试运行的历史记录。您可以按 Escape 关闭该视图,也可以通过打开用户设置(在命令面板中使用首选项: 打开设置 (UI)命令)并将 Testing: Automatically Open Peek View(测试: 自动打开速览视图)设置的值更改为 never
来禁用它。
在测试资源管理器中,会显示单个测试以及包含这些测试的任何类和文件的结果。如果文件夹中的任何测试未通过,文件夹将显示一个失败图标。
VS Code 也会在测试结果面板中显示测试结果。
带覆盖率运行测试
要启用覆盖率来运行测试,请选择测试资源管理器中的覆盖率运行图标,或从任何您通常触发测试运行的菜单中选择带覆盖率运行选项。如果您使用的是 pytest,Python 扩展会使用 pytest-cov
插件运行覆盖率测试;对于 unittest,则使用 coverage.py
。
在带覆盖率运行测试之前,请确保为您的项目安装了正确的测试覆盖率包。分支覆盖率仅在 coverage 版本 >= 7.7 时支持。
覆盖率运行完成后,编辑器中的代码行会根据行级覆盖率高亮显示。测试覆盖率结果会作为“测试覆盖率”子选项卡出现在测试资源管理器中,您也可以通过命令面板中的Testing: Focus on Test Coverage View(测试: 聚焦于测试覆盖率视图)(⇧⌘P(Windows、Linux 为 Ctrl+Shift+P))导航到该面板。在此面板上,您可以查看工作区中每个文件和文件夹的行覆盖率指标,以及相关的分支覆盖率。
为了在使用 pytest 时更精细地控制您的覆盖率运行,您可以编辑 python.testing.pytestArgs
设置以包含您的规范。当 pytest 参数 --cov
存在于 python.testing.pytestArgs
中时,Python 扩展将不会对覆盖率参数进行额外编辑,以使您的自定义生效。如果没有找到 --cov
参数,扩展将在运行前向 pytest 参数添加 --cov=.
,以在工作区根目录启用覆盖率。
有关测试覆盖率的更多信息,请访问 VS Code 的测试覆盖率文档。
调试测试
要调试测试,请右键单击函数定义旁边的行号槽装饰,然后选择调试测试,或选择测试资源管理器中该测试旁边的调试测试图标。
运行或调试测试不会自动保存测试文件。在运行测试之前,请务必保存对测试的更改,否则您可能会对结果感到困惑,因为它们仍然反映的是文件的先前版本!
您可以使用命令面板中的以下命令来调试测试:
- Test: Debug All Tests(测试: 调试所有测试)- 为您工作区中的所有测试启动调试器。
- Test: Debug Tests in Current File(测试: 调试当前文件中的测试)- 为您在编辑器中打开的文件中定义的测试启动调试器。
- Test: Debug Test at Cursor(测试: 调试光标处的测试)- 仅为编辑器中光标所在的测试方法启动调试器。您还可以使用测试资源管理器中的调试测试图标来为选定范围内的所有测试和所有已发现的测试启动调试器。
您还可以通过在您的 settings.json
文件中将 testing.defaultGutterClickAction
设置的值更改为 debug
,来更改单击行号槽装饰的默认行为,使其变为调试测试而不是运行测试。
调试器对测试的工作方式与其他 Python 代码相同,包括断点、变量检查等。要自定义调试测试的设置,您可以在工作区 .vscode
文件夹的 launch.json
或 settings.json
文件中指定测试调试配置,方法是向您的配置中添加 "purpose": ["debug-test"]
。当您运行Test: Debug All Tests(测试: 调试所有测试)、Test: Debug Tests in Current File(测试: 调试当前文件中的测试)和Test: Debug Test at Cursor(测试: 调试光标处的测试)命令时,将使用此配置。
例如,下面 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
文件的路径。提示:您可以通过在资源管理器视图中右键单击文件并选择复制路径来复制路径。
- 在您的项目根目录下创建一个
- 根据需要,将 Django 测试参数添加到
settings.json
文件中的"python.testing.unittestArgs": []
,并移除任何与 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
,您将在.env
文件中添加MANAGE_PY_PATH='./manage.py'
,并在 VS Code 设置中设置"python.testing.unittestArgs": ["--arg"]
。或者,您也可以在 Python 输出面板中找到 Python 扩展运行的命令。 - 如果您最初使用的是相对路径,请在设置
MANAGE_PY_PATH
环境变量时使用manage.py
文件的绝对路径。
测试命令
以下是 VS Code 中 Python 扩展支持的所有测试命令。这些都可以通过命令面板找到:
命令名称 | 描述 |
---|---|
Python: Configure Tests | 配置要与 Python 扩展一起使用的测试框架。 |
Test: Clear All Results | 清除所有测试状态,因为 UI 会在会话之间持久化测试结果。 |
Test: Debug All Tests | 调试所有已发现的测试。相当于 2021.9 版本之前的 Python: Debug All Tests。 |
Test: Debug Failed Tests | 调试在最近一次测试运行中失败的测试。 |
Test: Debug Last Run | 调试在最近一次测试运行中执行的测试。 |
Test: Debug Test at Cursor | 调试编辑器中光标所在的测试方法。类似于 2021.9 版本之前的 Python: Debug Test Method...。 |
Test: Debug Tests in Current File | 调试当前编辑器中处于焦点状态的文件中的测试。 |
Test: Go to Next Test Failure | 如果错误速览视图已打开,则打开并移动到资源管理器中下一个失败测试的速览视图。 |
Test: Go to Previous Test Failure | 如果错误速览视图已打开,则打开并移动到资源管理器中上一个失败测试的速览视图。 |
Test: Peek Output | 为失败的测试方法打开错误速览视图。 |
Test: Refresh Tests | 执行测试发现并更新测试资源管理器以反映任何测试的更改、添加或删除。类似于 2021.9 版本之前的 Python: Discover Tests。 |
Test: Rerun Failed Tests | 运行在最近一次测试运行中失败的测试。类似于 2021.9 版本之前的 Python: Run Failed Tests。 |
Test: Rerun Last Run | 调试在最近一次测试运行中执行的测试。 |
Test: Run All Tests | 运行所有已发现的测试。相当于 2021.9 版本之前的 Python: Run All Tests。 |
Test: Run All Tests with Coverage | 运行所有已发现的测试并计算您的代码被测试覆盖的程度。 |
Test: Run Test at Cursor | 运行编辑器中光标所在的测试方法。类似于 2021.9 版本之前的 Python: Run Test Method...。 |
Test: Run Test in Current File | 运行当前编辑器中处于焦点状态的文件中的测试。相当于 2021.9 版本之前的 Python: Run Current Test File。 |
Test: Show Output | 打开包含所有测试运行详细信息的输出。类似于 2021.9 版本之前的 Python: Show Test Output。 |
Testing: Focus on Test Explorer View | 打开测试资源管理器视图。类似于 2021.9 版本之前的 Testing: Focus on Python View。 |
Test: Stop Refreshing Tests | 取消测试发现。 |
测试配置设置
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
的模式。
要在第一次失败时停止测试运行,请将 fail fast 选项 "-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 。 |