How do I print to the console in pytest?
I am using pytest to run my tests, but print statements do not appear in the console output. The documentation suggests that print should work by default. Here is the test code I’m running with pytest my_tests.py:
import myapplication as tum
class TestBlogger:
@classmethod
def setup_class(self):
self.user = “alice”
self.b = tum.Blogger(self.user)
print(“This should be printed, but it won’t be!”)
def test_inherit(self):
assert issubclass(tum.Blogger, tum.Site)
links = self.b.get_links(posts)
print(len(links)) # This won't print either.
The script being tested also contains print statements:
Why aren’t my print statements showing up in the pytest output, and how can I make pytest print to console work as expected?
By default, pytest captures the output of print statements to manage how it displays the results, which helps avoid clutter in the test output. If a test fails, pytest includes a “Captured stdout” section in the report, showing what was printed during that test.
For example:
def test_good():
for i in range(1000):
print(i)
def test_bad():
print('this should fail!')
assert False
Running this with pytest results in:
$ pytest tmp.py
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items
tmp.py .F
=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________
def test_bad():
print('this should fail!')
> assert False
E assert False
tmp.py:7: AssertionError
------------------------------- Captured stdout --------------------------------
this should fail!
====================== 1 failed, 1 passed in 0.04 seconds ======================
If you want to see print statements as they are executed, you can use the -s flag with pytest:
$ pytest tmp.py -s
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items
tmp.py 0
1
2
3
... and so on ...
997
998
999
.this should fail!
F
=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________
def test_bad():
print('this should fail!')
> assert False
E assert False
tmp.py:7: AssertionError
====================== 1 failed, 1 passed in 0.02 seconds ======================
Using the -s flag can be helpful for debugging, though it might make the output harder to interpret due to the volume of printed data.
The cleanest way to print a single statement to sys.stdout without making your test fail or using the -s option is to use the capsys fixture provided by pytest. This approach allows you to see specific output directly while keeping other output captured. Here’s how to do it:
Add capsys as a parameter to your test function:
def test_function(existing_parameters, capsys):
Use the capsys.disabled() context manager to bypass output capture and print directly to sys.stdout:
with capsys.disabled():
print(“This output will not be captured and will go straight to sys.stdout”)
For more details, you can refer to the pytest documentation on capturing output.
To print an important warning about skipped tests when pytest is running in silent mode (i.e., with output capturing enabled), you can use the atexit module to register a function that will print the message after pytest has finished and released the output streams.
This approach ensures that you can display the warning without failing a test. Here’s how to do it:
def test_2_YellAboutBrokenAndMutedTests():
import atexit
import sys
def report():
print("In silent mode, pytest breaks low-level stream structures I work with, so I cannot test if my functionality works fine. I skipped corresponding tests. Run `pytest -s` to make sure everything is tested.")
if sys.stdout != sys.__stdout__:
atexit.register(report)
In this example:
The report function defines the message you want to print. The atexit.register(report)
registers this function to be executed when the script terminates. The if sys.stdout != sys.__stdout__: condition
ensures that the message is only printed if pytest is capturing output, preventing it from being printed when pytest -s
is used.
This method provides a warning only when pytest’s output capture is enabled, and it is not printed if you run the tests with pytest -s
, which shows all output immediately.