9

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.)

1
  • Even assigning sys.__stdout__ and sys.__stderr__ fails here - I think it's impossible to redirect the output from within python itself. Commented Jan 9, 2013 at 21:04

2 Answers 2

14

redirect stderr, e.g.:

python my_unit_test_launcher.py 2> log.txt 
Sign up to request clarification or add additional context in comments.

3 Comments

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.
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.
output="$(python -u some_tests.py 2>&1)" && echo "$output" # I'm trying this and it still doesn't display anything.
10

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) 

1 Comment

TextTestRunner(stream=sys.stdout) is just what I was missing. Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.