Sometimes you don’t want output at all to your screen, there are times when I’m writing a function that prints something to the screen, the ideal thing (at least for me) is to use
return instead of
print() of course, but let’s say that you don’t have another option and when it comes to Unit Testing it becomes annoying. How can we suppress STDOUT?
We’re writing a simple script that greets someone:
Let’s run this code shall we? We’ll import it and use the function
from say_hi import salute
It works great. Now, to suppress the output of
salute(name) we’re going to redirect
sys.stdout into a StringIO to capture any text output:
# remember to import io and sys
If we execute this python code, no output will be displayed. This is useful when we are Unit Testing and we want to suppress
print() output. If we want to check the captured test we can do this with
-- SNIP --
If we have a module that prints something to the screen instead of returning a value, we can test that
print() string with the method above. First, let’s remove everything from our previous code, leaving only our
Using the code above, what we want to do is to test if the method
salute(name) always prints a greeting in the following format:
Hi, __name__! (keep in mind that the function
print() always insert a new line, or
\n, at the end)
Let’s setup our Unit Test:
When we execute our code we obtain the following error:
$ python test_say_hi.py
Why our assertion didn’t work here?
'Hi, Anne!\n', right? It doesn’t. Print doesn’t return anything actually, it just prints something to the screen (to put it mildly), but it doesn’t returns a string.
But with our previous technique we can capture the string and store it in a value so we can compare our print string:
test_salute() we redirect our print to our
text_trap, and after restoring
stdout to its original functionality we can compare the value of
text_trap.getvalue() with our expected output:
And it works correctly, we can now compare our
There’s a much nicer and safer way to do this instead of rewriting
stdout, we can use a Context Manager temporarily redirect
sys.stdout without touching it.
And if we’re going to test
This is a much safer and cleaner approach, have fun!