Python 3.4.1, pytest 2.6.2.
When the test fails, pytest will regularly report what was printed to stdout with the test. For example, 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 the pytest built-in capsys tool, for example:
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 if this complies with the specification; The pytest documentation says about readouterr : "After the test function finishes, the original threads will be restored."
I tried to assume that capsys is a context manager and has called capsys.__exit__() just before the statements. That would be an ugly solution, but at least a solution if he restored the output to my approval. However, this only causes
AttributeError: 'CaptureFixture' object has no attribute '__exit__'
Next, I looked at the source code of the CaptureFixture class and found a promising close method (which calls some pop_outerr_to_orig() method), but the capsys.close() call did not help in my test, it had no obvious effect.
How can I get pytest to report my findings when a test fails using capsys ?