在 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 也会在测试结果面板中显示测试结果。
运行带覆盖率的测试
要运行启用覆盖率的测试,请选择测试资源管理器中的覆盖率运行图标,或从任何您通常触发测试运行的菜单中选择Run with coverage (带覆盖率运行) 选项。如果您使用的是 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
设置以包含您的规范。当 python.testing.pytestArgs
中存在 pytest 参数 --cov
时,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 。 |