How can I redirect the output of unittest? Obvious solution doesn't work

10,245

Solution 1

redirect stderr, e.g.:

python my_unit_test_launcher.py 2> log.txt

Solution 2

To solve it within your testcode, you could also do the following:

import sys
import unittest

class DemoTest(unittest.TestCase):
    def test_one(self):
        print "test one"
        self.assertTrue(True)

    def test_two(self):
        print "test two"
        self.assertTrue(False)

if __name__ == "__main__":
    demo_test = unittest.TestLoader().loadTestsFromTestCase(DemoTest)
    unittest.TextTestRunner(stream=sys.stdout).run(demo_test)
Share:
10,245
tadasajon
Author by

tadasajon

Elixir!

Updated on June 04, 2022

Comments

  • tadasajon
    tadasajon almost 2 years

    Here is my code:

    import unittest
    import sys
    import os
    
    class DemoTest(unittest.TestCase):
        def test_one(self):
            print "test one"
            self.assertTrue(True)
    
        def test_two(self):
            print "test two"
            self.assertTrue(False)
    
    if __name__ == '__main__':
        dirpath = os.path.dirname(os.path.abspath(__file__))
        sys.stdout = open(dirpath+'/test_logs/demo_test.stdout.log', 'w')
        sys.stderr = open(dirpath+'/test_logs/demo_test.stderr.log', 'w')
        test_program = unittest.main(verbosity=0, exit=False)
    

    When I run this, the contents of demo_test.stdout.log is only:

    test one
    test two
    

    on the screen I still see the output from unittest:

    ======================================================================
    FAIL: test_two (__main__.DemoTest)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "demotest.py", line 12, in test_two
        self.assertTrue(False)
    AssertionError: False is not true
    
    ----------------------------------------------------------------------
    Ran 2 tests in 0.000s
    
    FAILED (failures=1)
    

    I want there to be no output on the screen and everything to be logged. (I am running the test as a cron job, so any output to stdout or stderr causes an email to be sent, so I want to be able to specify exactly when this happens, which means I need to be able to control unittest in this regard.)

  • tadasajon
    tadasajon over 11 years
    okay, this seems to work. I'm still not sure why stderr isn't getting redirected anyway, since I explicitly set it to be redirected in my program.
  • Silas Ray
    Silas Ray over 11 years
    Because unittest runs your test code in a sandbox that wraps std streams. You are redirecting the output of your test code, but unittest doesn't care, because unittest normally just captures your output as basically that of a child process then regurgitates it to the context that called it. The output you are seeing, from unittest itself, is completely independent of what you do in the test code.
  • Seng Cheong
    Seng Cheong about 7 years
    TextTestRunner(stream=sys.stdout) is just what I was missing. Thanks!
  • Alex Jansen
    Alex Jansen about 5 years
    output="$(python -u some_tests.py 2>&1)" && echo "$output" # I'm trying this and it still doesn't display anything.