Reputation: 31262
This Article describes how to use pytest for capturing console outputs. I tried the following code, but I get an error
import sys
import pytest
def f(name):
print "hello "+ name
def test_add(capsys):
f("Tom")
out,err=capsys.readouterr()
assert out=="hello Tom"
test_add(sys.stdout)
Output:
python test_pytest.py
hello Tom
Traceback (most recent call last):
File "test_pytest.py", line 12, in <module>
test_add(sys.stdout)
File "test_pytest.py", line 8, in test_add
out,err=capsys.readouterr()
AttributeError: 'file' object has no attribute 'readouterr'
I have also tried to replace capsys
with capfd
, but get the same error.
What is wrong and how can it be fixed?
Upvotes: 49
Views: 40788
Reputation: 19050
Use the capfd
fixture.
Example:
def test_foo(capfd):
foo() # Writes "Hello World!" to stdout
out, err = capfd.readouterr()
assert out == "Hello World!"
See: http://pytest.org/en/latest/fixture.html for more details
And see: py.test --fixtures
for a list of builtin fixtures.
Your example has a few problems. Here is a corrected version:
def f(name):
print("hello " + name)
def test_f(capfd):
f("Tom")
out, err = capfd.readouterr()
assert out == "hello Tom\n"
Note:
sys.stdout
-- Use the capfd
fixture as-is as provided by pytest.py.test foo.py
Test Run Output:
$ py.test foo.py
====================================================================== test session starts ======================================================================
platform linux2 -- Python 2.7.5 -- pytest-2.4.2
plugins: flakes, cache, pep8, cov
collected 1 items
foo.py .
=================================================================== 1 passed in 0.01 seconds ====================================================================
Also Note:
py.test
(The CLI tool and Test Runner) does this for you.py.test does mainly three things:
By default py.test
looks for (configurable iirc) test_foo.py
test modules and test_foo()
test functions in your test modules.
Upvotes: 70
Reputation: 39426
The problem is with your explicit call of your test function at the very end of your first code snippet block:
test_add(sys.stdout)
You should not do this; it is pytest's job to call your test functions.
When it does, it will recognize the name capsys
(or capfd
, for that matter)
and automatically provide a suitable pytest-internal object for you as a call argument.
(The example given in the pytest documentation is quite complete as it is.)
That object will provide the required readouterr()
function.
sys.stdout
does not have that function, which is why your program fails.
Upvotes: 8