如何在pytest中同时声明UserWarning和SystemExit

时间:2019-09-28 03:02:11

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

在pytest中声明UserWarning和SystemExit

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

代码类似于:

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中?

2 个答案:

答案 0 :(得分:2)

members = models.ManyToManyField( Person, related_name='mess_members', default=self.admin, blank=True, ) package com.example.helppido; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; public class LoginActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); } } 是常用的上下文管理器,当用逗号分隔时,可以在单个pytest.warns语句中声明(请参见compound statements):

pytest.raises

实际上与写作相同

with

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

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

将按预期失败。

答案 1 :(得分:1)

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

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