pythonprintingstdoutpytest

Writing a pytest function for checking the output on console (stdout)


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?


Solution

  • 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:

    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 does mainly three things:

    1. Collect your tests
    2. Run your tests
    3. Display statistics and possibly errors

    By default py.test looks for (configurable iirc) test_foo.py test modules and test_foo() test functions in your test modules.