【问题标题】:Verify the error code or message from SystemExit in pytest验证来自 pytest 中 SystemExit 的错误代码或消息
【发布时间】:2019-08-01 07:29:58
【问题描述】:

根据 pytest 文档,我可以断言 SystemExit() 发生,但我想做更多:我还想验证退出代码和任何消息。我尝试了下面的代码,但没有打印出来,我不确定我需要断言什么来证明我得到了正确的错误代码。

    with pytest.raises(SystemExit):
        docopt_args = validate_args(docopt_args)
        out, err = pytest.capsys.readouterr()
        assert out == 'Foo'
        print out, err

当我运行我的测试时,它通过了,但就是这样。没有打印任何内容,并且我没有收到断言错误。

我期望执行的代码是:

        print '\n' + docopt_args['-d'] + ' is not a valid date\n'
        sys.exit(-3)

【问题讨论】:

标签: python pytest


【解决方案1】:

这适用于最新的pytest

您需要做的就是使用--capture=sys 选项运行pytest,并在raises() 上下文之外依赖断言(由于某种原因,这一点很重要!

示例:

#!/usr/bin/env python

from __future__ import print_function

import pytest


def f(code=0):
    print("Foo")
    raise SystemExit(code)


def test_f(capsys):
    with pytest.raises(SystemExit):
        f()
    out, err = capsys.readouterr()
    assert out == "Foo\n"
    print(out, err)

演示:

$ py.test -v --capture=sys test_foo.py 
======================================= test session starts ========================================
platform linux2 -- Python 2.7.9 -- py-1.4.27 -- pytest-2.7.0 -- /home/prologic/.virtualenvs/test/bin/python
rootdir: /home/prologic/tmp, inifile: 
collected 1 items 

test_foo.py::test_f PASSED

===================================== 1 passed in 0.00 seconds =====================================

print("Foo") 更改为print("Bar") 会导致:

$ py.test -v --capture=sys test_foo.py 
======================================= test session starts ========================================
platform linux2 -- Python 2.7.9 -- py-1.4.27 -- pytest-2.7.0 -- /home/prologic/.virtualenvs/test/bin/python
rootdir: /home/prologic/tmp, inifile: 
collected 1 items 

test_foo.py::test_f FAILED

============================================= FAILURES =============================================
______________________________________________ test_f ______________________________________________

capsys = <_pytest.capture.CaptureFixture instance at 0x7f2729405518>

    def test_f(capsys):
        with pytest.raises(SystemExit):
            f()
        out, err = capsys.readouterr()
>       assert out == "Foo\n"
E       assert 'Bar\n' == 'Foo\n'
E         - Bar
E         + Foo

test_foo.py:17: AssertionError
===================================== 1 failed in 0.01 seconds =====================================

我认为这正是你所追求的!

我在一个干净的virtualenv中做到了这一点:

mkvirtualenv test
pip install pytest

这里的诀窍是阅读和理解Setting capturing methods or disabling capturing

【讨论】:

  • 要对现有代码进行断言,您需要这样的内容:“with pytest.raises(SystemExit) as excinfo: assert excinfo.value.code==1”
  • 就我而言,我没有尝试捕获给出的代码(我只需要测试SystemExit 是否被提出),它对我来说很好。您可以通过注释掉您的测试代码并输入 a = 1 或类似的内容来验证它是否确实有效,因为 SystemExit 没有被引发。
  • 根据 mvr 的评论制作 Checking the exit code of a CLI in a test。令人惊讶的是,没有一篇直截了当的帖子涵盖这个主题。
猜你喜欢
  • 2021-06-13
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 2011-05-11
  • 1970-01-01
  • 1970-01-01
  • 2022-10-13
  • 2014-05-01
相关资源
最近更新 更多