Как я могу перенаправить вывод unittest? Очевидное решение не работает

Вот мой код:

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)

Когда я запускаю это, содержимое demo_test.stdout.log только:

test one
test two

на экране я все еще вижу вывод 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)

Я хочу, чтобы на экране не было вывода и все логировалось. (Я запускаю тест как задание cron, поэтому любой вывод на stdout или stderr вызывает отправку электронного письма, поэтому я хочу иметь возможность точно указать, когда это происходит, что означает, что мне нужно иметь возможность контролировать unittest в этом внимание.)


person jononomo    schedule 09.01.2013    source источник
comment
Даже назначение sys.__stdout__ и sys.__stderr__ здесь не работает - я думаю, что невозможно перенаправить вывод изнутри самого python.   -  person Eric    schedule 10.01.2013


Ответы (2)


перенаправить stderr, например:

python my_unit_test_launcher.py 2> log.txt
person Zaur Nasibov    schedule 09.01.2013
comment
хорошо, это, кажется, работает. Я все еще не уверен, почему stderr все равно не перенаправляется, поскольку я явно установил его для перенаправления в своей программе. - person jononomo; 10.01.2013
comment
Потому что unittest запускает ваш тестовый код в песочнице, обертывающей стандартные потоки. Вы перенаправляете вывод своего тестового кода, но unittest это не волнует, потому что unittest обычно просто фиксирует ваш вывод как в основном дочерний процесс, а затем извергает его в контекст, который его вызвал. Вывод, который вы видите, из самого unittest, полностью не зависит от того, что вы делаете в тестовом коде. - person Silas Ray; 10.01.2013
comment
output=$(python -u some_tests.py 2›&1) && echo $output # Я пытаюсь это сделать, но ничего не отображается. - person Alex Jansen; 01.03.2019

Чтобы решить эту проблему в своем тестовом коде, вы также можете сделать следующее:

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)
person spoorcc    schedule 28.03.2014
comment
TextTestRunner(stream=sys.stdout) это именно то, чего мне не хватало. Спасибо! - person Jonathon Reinhart; 12.04.2017