在 Visual Studio Code 中进行 Python 测试
此 Python 扩展 基于 VS Code 的内置 测试功能,提供针对 Python 内置的 unittest 框架和 pytest 的测试发现、测试覆盖率以及测试的运行和调试功能。
配置测试
安装 Python 扩展并在编辑器中打开 Python 文件后,VS Code 活动栏中会显示一个测试烧杯图标,代表 **Test Explorer(测试资源管理器)** 视图。打开测试资源管理器,如果尚未启用测试框架,会显示 **Configure Python Tests(配置 Python 测试)** 按钮。选择 **Configure Python Tests** 会提示你选择一个测试框架和一个包含测试的文件夹。如果使用 unittest,你还需要选择用于标识测试文件的文件 glob 模式。
文件 glob 模式是基于通配符来匹配文件或文件夹名称以包含或排除文件的定义字符串模式。

可以通过从 命令面板 中使用 **Python: Configure Tests(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 的空文件。
如果测试发现成功,你将在测试资源管理器中看到列出的测试。

当直接从测试资源管理器触发测试发现时,你也可以取消正在进行的测试发现调用。使用 **Cancel(取消)** 按钮,该按钮在发现过程中会替换 **Refresh(刷新)** 按钮。

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

运行测试
你可以通过以下任一操作来运行测试:
-
打开测试文件时,在测试定义行旁边的边栏中选择显示的绿色运行图标,如上一节所示。此命令仅运行该一个方法。

-
从命令面板运行以下任一命令:
- **Test: Run All Tests(测试: 运行所有测试)** - 运行所有已发现的测试。
- **Test: Run Tests in Current File(测试: 运行当前文件中的测试)** - 运行编辑器中打开的文件里的所有测试。
- **Test: Run Test at Cursor(测试: 运行光标处的测试)** - 仅运行编辑器中光标处的测试方法。
-
从 **Test Explorer(测试资源管理器)**:
-
要运行所有已发现的测试,请选择 **Test Explorer(测试资源管理器)** 顶部的播放按钮。

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

-
你还可以通过测试资源管理器运行选定的测试。为此,Ctrl+Click(macOS 上为 Cmd+Click)要运行的测试,右键单击其中一个,然后选择 **Run Test(运行测试)**。
-
测试运行后,VS Code 会直接在编辑器中以边栏装饰的形式显示结果。失败的测试也将在编辑器中高亮显示,并带有“Peek View”(预览视图),显示测试运行错误消息以及所有测试运行历史记录。你可以按 Escape 关闭该视图,也可以通过打开用户设置(在 **Command Palette(命令面板)** 中使用 **Preferences: Open Settings (UI)(首选项: 打开设置 (UI))** 命令)并将 **Testing: Automatically Open Peek View(测试: 自动打开预览视图)** 设置的值更改为 never 来禁用它。
在 **Test Explorer(测试资源管理器)** 中,会显示单个测试以及包含这些测试的类和文件的结果。如果文件夹中的任何测试未通过,文件夹将显示失败图标。

VS Code 还在 **Test Results(测试结果)** 面板中显示测试结果。

运行带覆盖率的测试
要运行带覆盖率的测试,请选择测试资源管理器中的覆盖率运行图标,或从你通常触发测试运行的任何菜单中选择 **Run with coverage(使用覆盖率运行)** 选项。如果你使用 pytest,Python 扩展将使用 pytest-cov 插件运行覆盖率;对于 unittest,则使用 coverage.py。
在运行带覆盖率的测试之前,请确保为项目安装了正确的测试覆盖率包。仅在 coverage 版本 >= 7.7 时支持分支覆盖率。
覆盖率运行完成后,编辑器中会高亮显示行覆盖率的行。测试覆盖率结果显示在测试资源管理器中的“Test Coverage”(测试覆盖率)子选项卡下,你也可以通过命令面板中的 **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 的 测试覆盖率文档。
调试测试
要调试测试,请右键单击函数定义旁边的边栏装饰,然后选择 **Debug Test(调试测试)**,或在 **Test Explorer(测试资源管理器)** 中选择该测试旁边的 **Debug Test(调试测试)** 图标。

运行或调试测试不会自动保存测试文件。在运行测试之前,请务必保存对测试的更改,否则你可能会因结果反映的是文件的旧版本而感到困惑!
你可以使用命令面板中的以下命令来调试测试:
- **Test: Debug All Tests(测试: 调试所有测试)** - 为工作区中的所有测试启动调试器。
- **Test: Debug Tests in Current File(测试: 调试当前文件中的测试)** - 为编辑器中打开的文件中定义的测试启动调试器。
- **Test: Debug Test at Cursor(测试: 调试光标处的测试)** - 仅为编辑器中你光标所在位置的方法启动调试器。你也可以使用测试资源管理器中的 **Debug Test(调试测试)** 图标来为所选范围内的所有测试以及所有已发现的测试启动调试器。
你还可以通过更改 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文件。 - 在
.env文件中添加MANAGE_PY_PATH='<path-to-manage.py>',将<path-to-manage.py>替换为你应用程序manage.py文件的路径。**提示**:你可以通过在资源管理器视图中右键单击文件并选择 **Copy Path(复制路径)** 来复制路径。
- 在项目根目录下创建一个
- 根据需要,将 Django 测试参数添加到
settings.json文件 的"python.testing.unittestArgs": []中,并删除任何与 Django 不兼容的参数。
默认情况下,Python 扩展会在项目根目录下查找并加载 .env 文件。如果你的 .env 文件不在项目根目录下,或者你正在使用 VS Code 变量替换,请在 settings.json 文件 中添加 "python.envFile": "${workspaceFolder}/<path-to-.env>"。这使得 Python 扩展在运行和发现测试时能够从该文件中加载环境变量。有关 Python 环境变量 的更多信息。
导航到 Testing(测试)视图,然后选择 **Refresh Tests(刷新测试)** 按钮,让你的 Django 测试显示出来!
故障排除
如果你的 Django 单元测试未显示在 Testing(测试)视图中,请尝试以下故障排除步骤:
- 在 **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文件的绝对路径,如果你最初使用的是相对路径。
测试命令
以下是 Python 扩展在 VS Code 中进行测试的所有支持的命令。这些命令都可以在命令面板中找到:
| Command Name(命令名称) | 描述 |
|---|---|
| Python: Configure Tests(Python: 配置测试) | 配置 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 本身提供,在 VS Code 设置编辑器中搜索“Testing”即可找到。
通用 Python 设置
| 设置 (python.testing.) |
默认值 | 描述 |
|---|---|---|
| autoTestDiscoverOnSaveEnabled | true |
指定是启用还是禁用在保存测试文件时自动运行测试发现。更改此设置后,您可能需要重新加载窗口才能使其生效。 |
| cwd | null | 指定测试的可选工作目录。此设置的存在会动态调整 pytest 的 --rootdir 参数。 |
| autoTestDiscoverOnSavePattern | **/*.py |
指定一个 glob 模式,该模式确定在 autoTestDiscoverOnSaveEnabled 为 true 时,哪些文件更改会触发自动测试发现。 |
| debugPort | 3000 |
用于调试 unittest 测试的端口号。 |
| promptToConfigure | true |
指定当发现潜在测试时,VS Code 是否提示配置测试框架。 |
unittest 配置设置
| Unittest setting(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 setting(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 setting(IntelliSense 设置) (python.analysis.) |
默认值 | 描述 |
|---|---|---|
| inlayHints.pytestParameters | false | 是否显示 pytest fixture 参数类型的内联提示。可接受的值为 true 或 false。 |