11

当我在检查了“未捕获的异常”的情况下在 vscode 调试器中运行 pytest 并且存在测试错误时,不会发生未捕获的异常,因为 pytest 捕获它们并进行结果报告。我如何告诉 pytest 让异常发生?这样我就可以在 vscode 调试器中捕获它们?

基本上我想要这样的行为,--pdb但我希望它启动 vscode 调试器而不是 pdb。这面旗帜--pdbcls听起来很有希望,但不知道该<module>:<class>给它什么。

注意:通常我只会让它在引发异常时中断。但是我们的代码有大量的引发但捕获的异常,所以这个选项没有用。

这是在调试 pytest 测试时触发 AssertionError 时 vscode 未中断的视频:

在此处输入图像描述

@rioV8 下面的建议确实打破了异常,但由于某种原因没有堆栈,这意味着您无法从那里进行调试:

在此处输入图像描述

我一定遗漏了一些东西,因为似乎没有其他人需要这种能力。但对我来说,这似乎绝对是使用测试框架和调试器可以做的最基本最简单的事情:作为一名开发人员,我想从引发错误的地方进行调试。

一定有一些完全不同的方式人们使用带有 pytest 的调试器,我忽略了一些明显的技术。

4

3 回答 3

17

我向 pytest 提出了一个问题,他们提出了一个可行的建议。将此添加到您的conftest.py

import os
import pytest

if os.getenv('_PYTEST_RAISE', "0") != "0":

    @pytest.hookimpl(tryfirst=True)
    def pytest_exception_interact(call):
        raise call.excinfo.value

    @pytest.hookimpl(tryfirst=True)
    def pytest_internalerror(excinfo):
        raise excinfo.value

然后在您的"request": "test"launch.json 中,您可以切换该环境变量:

    {
        "name": "Debug Tests",
        "type": "python",
        "request": "test",
        "console": "integratedTerminal",
        "justMyCode": true,
        "env": {
            "_PYTEST_RAISE": "1"
        },
    }

如果_PYTEST_RAISE已设置并且您仅选中未捕获异常框,您将在未捕获异常之前未引发的地方中断。

我也提出了一个问题debugpy他们有一些想法,但今天没有解决方案。这个_PYTEST_RAISE技巧100%为我解决了这个问题。

于 2020-06-24T19:57:36.117 回答
0

行为并不相同,但测试运行程序会在未捕获的异常处停止。

将文件添加conftest.py到包含测试的目录中。

# conftest.py
def pytest_exception_interact(node, call, report):
  print( call.excinfo.traceback[0] )
  pass

这为任何未捕获的异常添加了一个钩子。

在带有 的行处放置一个断点pass

然后Debug是测试。

查看调试控制台,您会看到发生异常的文件和行号。

test_example.py F  File 'path\\test_example.py':4 in test_example
  assert False

调试器停在该pass行。

你可以随心所欲地制作这个钩子函数。

于 2020-06-22T09:17:50.160 回答
0

我注意到一些可能相关的事情。尽管我现在还没有准备好深入挖掘,但我会将它们发布在这里,以防它们对某人有用。

解决方法:

我使用的一个简单技巧是(暂时)直接调用相关的测试用例并“运行和调试”文件,而不是使用“调试测试用例”按钮:


def test_example():
    assert False


test_example()

结果:

在此处输入图像描述

笔记:

  1. 行为的重要区别与在配置中指定"request": "test"与指定有关。(两种类型之间的区别在于选项是否从全局启动配置中应用,如此处所述"request": "launch"launch.jsonjustMyCode
  2. 如果您"request": "test"指定了 python,那么 VSCode 似乎不会像我上面那样让您在启动模式下调试文件。
  3. 在我的场景中,由于我在第三方库中引起的异常(当然是我的错),我的测试失败了。第三方代码中的断点显然只有在"justMyCode": false添加选项时才会触发。

启动.json:

{
    "version": "0.2.0",
    "configurations": [
        
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "justMyCode": false,            
        },
        // {
        //     "name": "Debug Unit Test",
        //     "type": "python",
        //     "request": "test",
        //     "console": "integratedTerminal",
        //     "justMyCode": false,
        // }        
    ]
}
于 2021-06-22T19:33:25.850 回答