Python 3.4.1, pytest 2.6.2.
When a test fails, pytest
will routinely report what was printed to stdout by the test.
For instance this code:
def method_under_test():
print("Hallo, Welt!")
return 41
def test_result_only():
result = method_under_test()
assert result == 42
when executed as python -m pytest myfile.py
,
will report this:
================================== FAILURES ===================================
______________________________ test_result_only _______________________________
def test_result_only():
result = method_under_test()
> assert result == 42
E assert 41 == 42
pytestest.py:9: AssertionError
---------------------------- Captured stdout call -----------------------------
Hallo, Welt!
========================== 1 failed in 0.03 seconds ===========================
This is a very nice feature.
But when I use pytest's built-in capsys
fixture, like this:
def test_result_and_stdout(capsys):
result = method_under_test()
out, err = capsys.readouterr()
assert out.startswith("Hello")
assert result == 42
the report no longer contains the actual output:
================================== FAILURES ===================================
___________________________ test_result_and_stdout ____________________________
capsys = <_pytest.capture.CaptureFixture object at 0x000000000331FB70>
def test_result_and_stdout(capsys):
result = method_under_test()
out, err = capsys.readouterr()
> assert out.startswith("Hello")
E assert <built-in method startswith of str object at 0x000000000330C3B0>('Hello')
E + where <built-in method startswith of str object at 0x000000000330C3B0> = 'Hallo, Welt!\n'.startswith
pytestest.py:14: AssertionError
========================== 1 failed in 0.03 seconds ===========================
I am not sure whether this behavior is according to specification;
the pytest documentation says about readouterr
:
"After the test function finishes
the original streams will be restored."
I have tried assuming capsys
is a context manager and have
called capsys.__exit__()
just before the asserts.
This would be an ugly solution, but at least a solution if
it restored the output before my assertion.
However, this only produces
AttributeError: 'CaptureFixture' object has no attribute '__exit__'
Next I looked into the CaptureFixture
class source code
and found a promising-looking method close
(which calls
some pop_outerr_to_orig()
method),
but calling capsys.close()
in my test did not help either,
it had no obvious effect at all.
How can I get pytest to report my outputs upon failure
in a test using capsys
?