pytest.raises 失败:没有通过 try/ except 引发

jef*_*new 8 python pytest

当使用 pytest.raises 测试由 try/ except 块捕获的错误时,由于未引发错误而失败。

如果我使用字典查找进行简单测试并且不对其进行尝试/例外,则 pytest.raises 测试会通过。但如果使用try/ except,则测试失败。

这是有效的:

def lookup_value(key):

    lookup = {'A': 1, 'B': 2}

    return lookup[key]


def test_lookup():

    with pytest.raises(KeyError):
        lookup_value('C')
Run Code Online (Sandbox Code Playgroud)

现在添加尝试/例外:

def lookup_value(key):

    lookup = {'A': 1, 'B': 2}

    try:
        return lookup[key]
    except KeyError as err:
        print(err)


def test_lookup():

    with pytest.raises(KeyError):
        lookup_value('C')
Run Code Online (Sandbox Code Playgroud)

第一个片段,测试通过。第二个片段,我得到“失败:没有提高<class 'KeyError'>”

Mar*_*k A 7

这里的代码正在吞噬异常(捕获它而不传播发生异常的事实)。

    try:
        return lookup[key]
    except KeyError as err:
        print(err)
Run Code Online (Sandbox Code Playgroud)

您只需要重新引发异常即可pytest.raises看到它

    try:
        return lookup[key]
    except KeyError as err:
        print(err)
        raise
Run Code Online (Sandbox Code Playgroud)

return此外,在函数末尾省略在另一个代码路径中返回某些内容的语句通常是不好的做法。在 Python 中,有一个隐含的return None,但为什么不通过显式地编写它来帮助读者一点呢?

  • 不,我想说的是,这种情况很少见。我不记得该模式的名称,但错误通常只应在有意义的地方处理一次。在您的示例中,您处理错误两次 - 一次在函数中(使用 print 调用),然后一次在调用者中(通过重新引发异常)。您可以考虑额外的打印调用是否会增加任何值,或者您是否只是让调用函数按照它认为合适的方式处理错误。或者调用者的调用函数,或者调用者的调用者的调用等等...... (2认同)