如何让 VS Code 将调试标准输出写入调试控制台?

War*_*ame 11 python pytest visual-studio-code

我正在尝试使用左侧栏上的测试活动在 VS Code 中调试我的 Python Pytest 测试。我能够按预期运行测试,有些通过,有些失败。我想调试失败的测试,以更准确地确定导致失败的原因。

当我在调试模式下运行单个测试时,VS Code 正确命中断点并停止,并且“运行和调试”窗格显示局部变量。我可以在“变量”>“本地”窗格中或通过 REPL 通过键入变量名称来观察局部变量的状态。

当我尝试打印任何语句(例如使用)时,> print("here")调试控制台没有得到任何输出。当我引用变量或直接使用字符串时,> "here"我确实看到了调试控制台的输出。

在我看来,我的 REPL 的标准输出没有显示到调试控制台。网上的许多答案都建议添加诸如"redirectOutput": true或 之类的选项"console": "integratedTerminal",但这些似乎都不起作用。我的完整内容launch.json如下:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "debugOptions": [
                "WaitOnAbnormalExit",
                "WaitOnNormalExit"
            ],
            "console": "integratedTerminal",
            "stopOnEntry": false,
            "redirectOutput": true,
            "outputCapture": "std"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我是否还缺少其他设置来启用此输出?我是否使用了错误的控制台类型?

Pab*_*blo 14

因此,经过大量令人沮丧的“调试”后,我找到了一个对我有用的解决方案(如果您pytest像我一样使用):

总览

两种解决方案:

  1. 将你的 vscode python 扩展降级到v2022.2.1924087327可以解决问题的版本(或任何具有 的版本debugpy<=1.5.1)。
    在此输入图像描述

  2. 或者,从而debug tab不是从testing tab. 并使用如下配置

    {
        "name": "Python: Current File (Integrated Terminal)",
        "type": "python",
        "request": "launch",
        "program": "${file}",
        "console": "integratedTerminal",
        "purpose": ["debug-test"], 
        "redirectOutput": true,
        "env": {"PYTHONPATH": "${workspaceRoot}"}
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 奖金。如果您正在使用,pytest您可以暂时禁用pytest 的 stdout 的捕获 ,以便您的 print 语句和print函数 *if you breakpoint inside contextmanager,也将起作用。这非常麻烦,但指出了为什么打印不再起作用的原始问题。

    def test_disabling_capturing(capsys):
        print('this output is captured')
        with capsys.disabled():
            print('output not captured, going directly to sys.stdout')
        print('this output is also captured')
    
    Run Code Online (Sandbox Code Playgroud)

长解释

所以问题显然是debugpy(Python调试器使用的库vscode)在最后一个版本中v1.6.0修复了这个“bug(827)”。简而言之,这个“错误”是 vscode 在调试时“复制”了所有标准输出,因为它捕获pytest stdout并在调试器控制台中复制它。这是因为,默认情况下,pytest捕获所有标准输出并存储它(因此当并行运行所有测试时,它不会造成混乱)。

“修复”此问题后,现在,当您通过 启动测试时testing tab,默认情况下pytest会捕获所有stdout,而“新”( >=v1.6.1)debugpy会忽略它。因此,即使在调用断点时,所有打印语句也不再显示在调试控制台上print(),因为它们是由 pytest 捕获的(IDK,其中pytest捕获的标准输出在任何地方都显示/存储)。就我而言,这是一个 PITA。

您可以pytest使用该标志-s--capture=no在控制台中启动 pytest 时甚至从调试选项卡作为自定义配置来禁用捕获选项。但问题是(显然)无法在 vscode 中添加这些参数,因此testing tabpytest 是使用该选项执行的。

因此,我找到的解决方案是将 python 扩展降级到使用旧版本的版本,您可以在python 扩展debugpy v1.5.1更改日志中看到,他们从版本更新版本,所以在这之前对我来说已经成功了,你控制台中将出现双“bug”,但该语句将起作用。2022.4.0debugpystdoutprint

参考:引导我找到解决方案的问题


您可以在 vscode-python issues中表达您的声音

  • 我能够将“-s”参数添加到测试选项卡中。我通过在项目的根目录中创建 pytest.ini 文件来完成此操作。然后我在“[pytest]”下添加了“addopts = -s” (2认同)