在pytest中验证来自SystemExit的错误代码或消息

2022-03-01 00:00:00 python pytest

问题描述

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

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

当我运行我的测试时,它通过了,但仅此而已。没有打印任何内容,并且我没有收到断言错误。

我希望执行的代码是:

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

解决方案

此功能适用于最新的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
"
    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
"
E       assert 'Bar
' == 'Foo
'
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

相关文章