在 Visual Studio Code 中进行 Python 测试
Python 扩展基于 VS Code 内置的测试功能,为 Python 内置的 unittest 框架和 pytest 提供测试发现、测试覆盖率以及运行和调试测试。
配置测试
当安装了 Python 扩展并且在编辑器中打开了一个 Python 文件时,VS Code 活动栏上会显示一个烧杯图标,表示测试资源管理器视图。如果未启用测试框架,打开测试资源管理器会显示一个配置 Python 测试按钮。选择配置 Python 测试会提示您选择一个测试框架以及包含测试的文件夹。如果您使用 unittest,还需要选择用于识别测试文件的文件全局模式。
文件全局模式是一种定义的字符串模式,它根据通配符匹配文件或文件夹名称以包含或不包含文件。
可以通过命令面板中的 Python: 配置测试 命令,或者通过在设置编辑器或 settings.json
文件中设置 python.testing.unittestEnabled
或 python.testing.pytestEnabled
来随时配置测试,如 VS Code 设置文档所述。每个框架还有特定的配置设置,如测试配置设置中所述,用于其文件夹和模式。
如果您启用了 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) 命令)并将测试:自动打开窥视视图设置的值更改为 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
设置以包含您的规范。当 python.testing.pytestArgs
中存在 pytest 参数 --cov
时,Python 扩展不会对覆盖率参数进行额外编辑,以允许您的自定义生效。如果未找到 --cov
参数,扩展将在运行前将 --cov=.
添加到 pytest 参数中,以启用工作区根目录的覆盖率。
有关测试覆盖率的更多信息,请访问 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
且参数中未指定 worker 计数时,Python 扩展会根据测试资源管理器中选定的测试数量自动优化 worker 数量。
Django 单元测试
Python 扩展还支持发现和运行 Django 单元测试!您只需几个额外的设置步骤即可发现您的 Django 测试:
- 在您的
settings.json
文件中设置"python.testing.unittestEnabled": true,
。 - 添加
MANAGE_PY_PATH
作为环境变量。- 在项目根目录创建
.env
文件。 - 将
MANAGE_PY_PATH='
添加到' .env
文件中,将
替换为您的应用程序manage.py
文件的路径。提示:您可以通过在资源管理器视图中右键单击文件并选择复制路径来复制路径。
- 在项目根目录创建
- 根据需要在
settings.json
文件中将 Django 测试参数添加到"python.testing.unittestArgs": []
,并删除任何与 Django 不兼容的参数。
默认情况下,Python 扩展会在项目根目录查找并加载 .env
文件。如果您的 .env
文件不在项目根目录或您正在使用 VS Code 变量替换,请将 "python.envFile": "${workspaceFolder}/
添加到您的 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 扩展的测试框架。 |
Test: 清除所有结果 | 清除所有测试状态,因为 UI 会跨会话持久保存测试结果。 |
Test: 调试所有测试 | 调试所有已发现的测试。在 2021.9 版本之前等同于 Python: 调试所有测试。 |
Test: 调试失败的测试 | 调试最近一次测试运行中失败的测试。 |
Test: 调试上次运行 | 调试最近一次测试运行中执行的测试。 |
Test: 调试光标处测试 | 调试编辑器中光标聚焦的测试方法。在 2021.9 版本之前类似于 Python: 调试测试方法...。 |
Test: 调试当前文件中的测试 | 调试编辑器中当前聚焦文件中的测试。 |
Test: 转到下一个测试失败 | 如果错误窥视视图已打开,则打开并移动到资源管理器中下一个失败测试的窥视视图。 |
Test: 转到上一个测试失败 | 如果错误窥视视图已打开,则打开并移动到资源管理器中上一个失败测试的窥视视图。 |
Test: 窥视输出 | 为失败的测试方法打开错误窥视视图。 |
Test: 刷新测试 | 执行测试发现并更新测试资源管理器以反映任何测试更改、添加或删除。在 2021.9 版本之前类似于 Python: 发现测试。 |
Test: 重新运行失败的测试 | 运行最近一次测试运行中失败的测试。在 2021.9 版本之前类似于 Python: 运行失败的测试。 |
Test: 重新运行上次运行 | 调试最近一次测试运行中执行的测试。 |
Test: 运行所有测试 | 运行所有已发现的测试。在 2021.9 版本之前等同于 Python: 运行所有测试。 |
Test: 运行所有带覆盖率的测试 | 运行所有已发现的测试并计算您的代码被测试覆盖的程度。 |
Test: 运行光标处测试 | 运行编辑器中光标聚焦的测试方法。在 2021.9 版本之前类似于 Python: 运行测试方法...。 |
Test: 运行当前文件中的测试 | 运行编辑器中当前聚焦文件中的测试。在 2021.9 版本之前等同于 Python: 运行当前测试文件。 |
Test: 显示输出 | 打开包含所有测试运行详细信息的输出。在 2021.9 版本之前类似于 Python: 显示测试输出。 |
Testing: 聚焦测试资源管理器视图 | 打开测试资源管理器视图。在 2021.9 版本之前类似于 Testing: 聚焦 Python 视图。 |
Test: 停止刷新测试 | 取消测试发现。 |
测试配置设置
使用 Python 进行测试的行为由 VS Code 提供的通用 UI 设置以及特定于 Python 和您已启用的框架的设置驱动。
通用 UI 设置
影响测试功能 UI 的设置由 VS Code 本身提供,当您搜索“测试”时,可以在 VS Code 设置编辑器中找到。
通用 Python 设置
设置 (python.testing.) |
默认值 | 描述 |
---|---|---|
autoTestDiscoverOnSaveEnabled | true |
指定在保存测试文件时是否启用或禁用自动运行测试发现。更改此设置后可能需要重新加载窗口才能使其生效。 |
cwd | null | 指定测试的可选工作目录。此设置的存在会动态调整 pytest 的 --rootdir 参数。 |
autoTestDiscoverOnSavePattern | **/*.py |
指定一个全局模式,用于确定当 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 。 |