【问题标题】:How to assert both UserWarning and SystemExit in pytest如何在 pytest 中同时断言 UserWarning 和 SystemExit
【发布时间】:2019-09-28 03:02:11
【问题描述】:

在 pytest 中断言 UserWarning 和 SystemExit

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

代码类似于:

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

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

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

如果我想检查警告:

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

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

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

【问题讨论】:

    标签: python unit-testing pytest systemexit user-warning


    【解决方案1】:

    pytest.warnspytest.raises 是常用的上下文管理器,可以在单个with 语句中声明,用逗号分隔(请参阅compound statements):

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

    这实际上与写作相同

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

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

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

    这和写是一样的

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

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

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

    将通过,因为pytest.warns 中引发的错误将在pytest.raises 中被吞噬,而

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

    会按预期失败。

    【讨论】:

      【解决方案2】:

      您可以像这样嵌套两个异常:

      def test_exit():
          with pytest.raises(SystemExit):
              error_msg = "warning here"
              with pytest.warns(UserWarning, match = error_msg):
                  compare_tags(...)
      

      【讨论】:

        猜你喜欢
        • 2019-04-25
        • 2021-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-14
        • 1970-01-01
        • 2018-04-05
        • 1970-01-01
        相关资源
        最近更新 更多