如何在 pytest 中同时断言 UserWarning 和 SystemExit [英] How to assert both UserWarning and SystemExit in pytest

查看:40
本文介绍了如何在 pytest 中同时断言 UserWarning 和 SystemExit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 pytest 中声明 UserWarning 和 SystemExit

在我的应用程序中,我有一个函数,当提供错误的参数值时,会从 warnings 模块引发 UserWarnings,然后从 SystemExit 引发sys 模块.

In my application I have a function that when provided with wrong argument values will raise a UserWarnings from warnings module and then raises SystemExit from sys module.

代码类似于:

def compare_tags(.....):

    requested_tags = user_requested_tags # as list
    all_tags = tags_calculated_from_input_file  # as list 

    non_matching_key = [x for x in requested_tags if x not in all_tags]

    # if user requested non existing tag then raise warning and then exit 
    if len(non_matching_key) > 0:

        # generate warning
        warnings.warn("The requested '%s' keys from '%s' is not present in the input file. Please makes sure the input file has the metadata of interest or remove the non matching keys." %(non_matching_key, given_tags))

        # raise system exit
        sys.exit(0)

为上述函数编写一个pytest

我想同时在 pytest 中测试这个 UserWarningSystemExit.我可以在 pytest 中检查 SystemExit 为.

I want to test this UserWarning and SystemExit in pytest at once. I can check for SystemExit in the pytest as.

with pytest.raises(SystemExit):
    compare_tags(....)

但这也会显示警告消息(这不是错误).

but this will also dispaly a warning message (which is not an error).

如果我想检查警告:

pytest.warns(UserWarning, 
    compare_tags(...)

这会产生一个SystemExit错误,因为这个被调用的函数会触发系统退出.

This will generate a SystemExit error because this called function will trigger system exit.

如何将 warningsSystemExit 检查放在同一个 pytest 中?

How can I put both the warnings and SystemExit check in the same pytest?

推荐答案

pytest.warnspytest.raises 是常用的上下文管理器,可以在单个with 用逗号分隔的语句(参见 复合语句):

pytest.warns and pytest.raises are the usual context managers and can be declared in a single with statement when separated with a comma (see compound statements):

with pytest.warns(UserWarning), pytest.raises(SystemExit):
    compare_tags(...)

这实际上与写作相同

with pytest.warns(UserWarning):
    with pytest.raises(SystemExit):
        compare_tags(...)

请注意顺序很重要 - 当您将两个上下文管理器按相反顺序放置时:

Notice that the order matters - when you put both context managers in the reverse order:

with pytest.raises(SystemExit), pytest.warns(UserWarning):
    ...

这和写作一样

with pytest.raises(SystemExit):
    with pytest.warns(UserWarning):
        ...

这里的问题是 pytest.raises 将捕获所有引发的错误,然后检查捕获的内容.这包括 pytest.warns 引发的内容.这意味着

The problem here is that pytest.raises will capture all raised errors and then check for what's captured. This includes what pytest.warns raises. This means that

with pytest.raises(SystemExit), pytest.warns(UserWarning):
    sys.exit(0)

会通过,因为 pytest.warns 中引发的错误会被 pytest.raises 吞掉,而

will pass because the error raised in pytest.warns will be swallowed in pytest.raises, while

with pytest.warns(UserWarning), pytest.raises(SystemExit):
    sys.exit(0)

会按预期失败.

这篇关于如何在 pytest 中同时断言 UserWarning 和 SystemExit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆