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

Rob*_*ler 12 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
Run Code Online (Sandbox Code Playgroud)

当我运行我的测试时,它会通过,但就是这样.什么都没打印,我没有得到断言错误.

我希望执行的代码是:

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

Jam*_*lls 14

这适用于最新的pytest:

您需要做的就是pytest使用该--capture=sys选项运行并将断言置于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)
Run Code Online (Sandbox Code Playgroud)

演示:

$ 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 =====================================
Run Code Online (Sandbox Code Playgroud)

更改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 =====================================
Run Code Online (Sandbox Code Playgroud)

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

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

mkvirtualenv test
pip install pytest
Run Code Online (Sandbox Code Playgroud)

这里的技巧是阅读和理解设置捕获方法或禁用捕获

  • 要对存在的代码进行断言,你需要这样的东西:"用pytest.raises(SystemExit)作为excinfo:assert excinfo.value.code == 1" (6认同)

mik*_*ent 8

詹姆斯·米尔斯的回答并没有完全回答这个问题。capsys这是最容易的一点。

正如 mvr 的评论中提到的,要返回退出代码,请执行以下操作:

with pytest.raises(SystemExit) as excinfo:
    run_something()

assert excinfo.value.code == 1
Run Code Online (Sandbox Code Playgroud)