Explain Codes LogoExplain Codes Logo

How do I print to console in pytest?

python
pytest
testing
output-capturing
Anton ShumikhinbyAnton Shumikhin·Nov 20, 2024
TLDR

Console output in pytest is activated with the -s flag. It suppresses the standard output capture, allowing print calls to appear directly in the console:

pytest -s your_test_module.py # Unleash the power of prints!

This lets you see print outputs on-the-go without modifying test configurations.

Unraveling pytest's output capturing

A primer on pytest's output capturing

By default, pytest captures all stdout and stderr during the testing process. This output is primarily used for providing a cleaner report after the tests. However, it only shows the outputs for failing tests.

Commanding different captures

Control the capturing mechanism via the --capture=method command. Customize it to use different capturing methods:

  • --capture=sys (default): Capturing confines to a Python string.
  • --capture=fd: File descriptor-based capturing.
  • --capture=no or -s: Completely disables capturing.

The power of pytest's fixtures

The fixture capsys allows you to capture prints for inspection within the test functions while providing an additional ability to interact with the output.

Temporary shut-off within the test

The capsys fixture provides a nifty way to disable capturing within a specific part of the test:

def test_something(capsys): with capsys.disabled(): print("This will print to the console, defying the Zen of pytest!") # Resistance is futile!

Forcing the output in case of despair

Although discouraged, one workaround is to use assert False, this forces the test to fail and pytest will splurge out all the captured data. A handy trick when -s is not an option!

Advanced output manipulation and silent mode evasion

Tapping into Python's atexit module

The atexit module in Python allows functions to execute at program termination. These can prove handy to display vital messages after all tests have run:

import atexit # There's always light at the end of the tunnel... sometimes you just gotta make it! def farewell_message(): print("All tests done! Time for a ☕ break!") atexit.register(farewell_message)

Saving outputs for later review

You don't need to rerun tests to review outputs, use file redirection:

pytest --capture=fd --outfile=output.log # Technically not printing to a console, but hey, it's output!

Is pytest keeping secrets?

Detect if pytest is in silent mode by checking stdout:

import sys assert sys.stdout is sys.__stdout__ # Sometimes it's good to be assertive. See what I did there?

Consistent reporting function

Enjoy recurring messages? Implement a common report() function using atexit:

import atexit def report(message): print(message) atexit.register(report, "Ssh...! Tests are now completed.") # A silent finishing touch!

Proficiency tips on output, silence, and beyond

Balancing verbosity and silence

While useful, too much -s can make test outputs resemble a chaotic mess. Be judicious with the verbosity of your tests.

Dealing with CI/CD environments

If pytest is running inside a CI/CD pipeline, output handling can vary. You may need -s to see the logs in your CI's logs.

Shy away from print debugging

Rethink if you're overusing print() for debugging. Pytest supports an array of logging methods that provide a more structured way to track tests.

Continuous learning

Stay updated with the pytest documentation. It's a great resource for latest features, best practices, and the wonderful world of pytest.