Capture stdout and stderr with pytest capsys

Use pytest's capsys fixture to capture and assert on standard output and error streams in your tests.

Easy Python 3.9+ Aug 9, 2026 Testing & modern typing 12 views 0 copies

Requires third-party packages — install first
pip install pytest

Python code

31 lines
Python 3.9+
import pytest

# Function under test
def greet(name):
    print(f"Hello, {name}!")
    print(f"Error: {name} not found", file=sys.stderr)

def test_captures_stdout_and_stderr(capsys):
    greet("Alice")
    captured = capsys.readouterr()
    
    assert "Hello, Alice!" in captured.out
    assert "Error: Alice not found" in captured.err
    assert captured.out.count("Hello") == 1

def test_partial_capture(capsys):
    print("to stdout")
    print("to stderr", file=sys.stderr)
    
    # Capture only stdout, leaving stderr intact
    captured_out = capsys.readouterr().out
    assert "to stdout" in captured_out
    
    # Restore and verify stderr still available
    captured_full = capsys.readouterr()
    assert "to stderr" in captured_full.err

if __name__ == "__main__":
    import sys
    # Run tests programmatically for demonstration
    pytest.main(["-v", "-s", __file__])

Output

stdout
No explicit output shown — the test failures or passes are displayed in terminal.

How it works

The capsys fixture automatically captures writes to sys.stdout and sys.stderr during each test. After the test's code has run, capsys.readouterr() returns a snapshot of the captured output as a named tuple with out and err fields. Calling readouterr() again after writing more output resets the captured text, letting you capture different sections of a test's output independently. This makes it easy to assert on specific messages your code printed without worrying about output to the real console.

Common mistakes

  • Forgetting to call `readouterr()` before assertions, resulting in empty captured strings
  • Using `captured.out` and `captured.err` interchangeably — they capture different streams
  • Not resetting the capture with `readouterr()` when testing multiple print statements in one test

Variations

  1. Use `capsysbinary()` to capture bytes instead of text for binary output
  2. Check the output with regex using `re.search` when exact string matching isn't enough

Real-world use cases

  • Verifying logging calls write expected messages to stderr in error-handling code
  • Testing CLI tools that print progress updates or prompts to stdout
  • Checking that background threads produce correct console output during integration tests

Sponsored

Run locally

This sample needs third-party packages, so it cannot run in the browser IDE. Copy the code above, install the packages shown at the top, then run it in your own Python environment.

More from Testing & modern typing

Related tutorials and quizzes for this topic.