35

Edit: Please notice I'm using Python 2.6 (as tagged)

Say I have the following:

class Foo:
    def bar(self):
        print 'bar'
        return 7

And say I have the following unit test:

import unittest
class ut_Foo(unittest.TestCase):
    def test_bar(self):
        obj = Foo()
        res = obj.bar()
        self.assertEqual(res, 7)

So if I run:

unittest.main()

I get:

bar # <-- I don't want this, but I *do* want the rest
.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
Exit code:  False

My question is: Is there a way to suppress the output of the object being tested while still getting the output of the unittest framework?

Edit This question is not a duplicate of the flagged question which is asking about silencing stdout of a particular function within a normal python script.

Whereas this question is asking about hiding the normal stdout of a python script while running it's unittests. I still want the unittest stdout to be displayed, and I don't want to disable the stdout of my tested script.

Yep_It's_Me
  • 4,494
  • 4
  • 43
  • 66
asherbret
  • 5,439
  • 4
  • 38
  • 58
  • See this post on how to silence a function: http://stackoverflow.com/questions/2828953/silence-the-stdout-of-a-function-in-python-without-trashing-sys-stdout-and-resto – otus Jun 10 '14 at 06:40
  • 5
    This is not a duplicate of the question provided... – Stefan Collier Jun 14 '18 at 16:07

2 Answers2

49

Call your unittest with option "-b" - buffer stdout and stderr

Foo.py

class Foo:
    def bar(self):
        print "bar"
        return 7

test.py

import unittest
from Foo import Foo

class test_Foo(unittest.TestCase):
    def test_bar(self):
        obj = Foo()
        res = obj.bar()
        self.assertEqual(res, 7)

if __name__ == "__main__":
    unittest.main()

Run it with -b option

$ python test.py -b
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Alternative: use nose

$ pip install nose

what installs command nosetests

Note, that I have modified test suite to have class and methods prefixed by test to satisfy nose default test discovery rules.

nosetests by default does not show output

$ nosetests
.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK

If you want to see the output, use -s switch:

$ nosetests -s
bar
.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
Jan Vlcinsky
  • 42,725
  • 12
  • 101
  • 98
  • 2
    Reference: https://docs.python.org/2/library/unittest.html#cmdoption-unittest-b – Maxime Lorant Jun 10 '14 at 06:44
  • 21
    You can also use `unittest.main(buffer=True)` to have this as default – KillianDS Jun 10 '14 at 06:47
  • 1
    This works well with python 2.7 however I asked about python 2.6 which, sadly, does not support this option. – asherbret Jun 10 '14 at 07:59
  • @user2016436 Sorry, I was not paying attention to all (very clearly stated) details of your question. You are right, that the `buffer` option was added at Python 2.7 and is missing in Python 2.6. However, the `nose` solution shall work (even though there might be slight differences in cornercases) – Jan Vlcinsky Jun 10 '14 at 08:39
  • 1
    Note that `-b` helps suppressing python print statements, but not output from binaries called by the code for example using subprocess.run. – Zitrax Mar 06 '19 at 12:37
10

You can suppress the output by disabling the sys.stdout and enabling it after your test is done:

import sys
import io
import unittest

class ut_Foo(unittest.TestCase):
    def test_bar(self):

        #You suppress here:
        suppress_text = io.StringIO()
        sys.stdout = suppress_text 
        
        obj = Foo()
        res = obj.bar()
        self.assertEqual(res, 7)
        
        #You release here:
        sys.stdout = sys.__stdout__

Got all of this from:

https://codingdose.info/2018/03/22/supress-print-output-in-python/

Ralf
  • 16,086
  • 4
  • 44
  • 68
Mbuso
  • 131
  • 1
  • 8
  • 9
    I found using the `with` statment and a mock, a better syntax, something like: `with mock.patch('sys.stdout', new = StringIO()) as std_out:` – Avizipi Jan 18 '21 at 13:50