How to see normal stdout/stderr console print() output from code during a pytest run?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Pytest captures stdout and stderr by default so test output stays clean and focused on failures. That is useful most of the time, but when you are debugging a test or inspecting real-time output, you need to know how to disable capture or work with it deliberately.
The Quick Answer: Use -s
If you want print output to appear live in the terminal during the test run, disable capture entirely.
This is equivalent to:
With capture disabled, normal print() calls and writes to sys.stderr show up immediately in the console.
Understanding Pytest Capture Modes
Pytest supports several capture modes, and choosing the right one matters:
- '
--capture=noor-s: no capture, output goes straight to the terminal' - '
--capture=sys: captures Python-level writes tosys.stdoutandsys.stderr' - '
--capture=fd: captures file descriptor writes, including many subprocess outputs' - '
--capture=tee-sys: shows Python output live while still capturing it for reports'
That last mode is especially useful when you want live visibility without giving up captured output in failure reports.
Captured Output Is Still Visible on Failure
Even with normal capture enabled, pytest often shows captured output when a test fails. That means you may not need -s for every debugging session.
If this test fails, pytest usually includes the captured output in the failure report.
Use capsys When You Want to Assert on Output
Sometimes you do not want live terminal output at all. You want to inspect what the code printed as part of the test itself. That is what the capsys fixture is for.
This keeps the test deterministic while still letting you work with output explicitly.
Use capfd for Lower-Level Writes
If the code under test writes at the file descriptor level, or if a subprocess is involved, capsys may not be enough. Use capfd instead.
This matters when native code, subprocesses, or lower-level writes are part of the test path.
Temporarily Disable Capture Inside One Test
You can also keep normal capture enabled and disable it only around a small block of code.
This is useful when you want just a short interactive debugging window without changing the entire test command.
Logging Is Often Better Than print
If the goal is diagnostic visibility rather than quick local debugging, structured logging may be a better tool than raw print() statements. Pytest integrates with Python logging and can display captured logs in failure output more cleanly than unstructured console prints.
Still, print() remains useful for short-lived investigation and simple examples.
Common Pitfalls
The biggest pitfall is assuming pytest "hides" output permanently. In most cases it captures output, and that captured text is still available in failure reports or via fixtures.
Another issue is using capsys when the code writes at the file descriptor level. In that case, capfd is often the right fixture.
Developers also disable capture globally with -s and then forget that this can make large test runs noisy and harder to scan.
Finally, do not confuse output capture with logging configuration. print() output and logging output are related only in the sense that both can appear during test runs; they are controlled differently.
Summary
- Use
pytest -sorpytest --capture=noto see livestdoutandstderr. - Use
--capture=tee-syswhen you want live Python output and captured reports. - Use
capsysto assert on printed output in a test. - Use
capfdwhen lower-level file descriptor output or subprocess output is involved. - Disable capture only where needed so normal test runs stay readable.

