Подтвердить что ты не робот

Запустите Python unittest, чтобы при печати ничего не печаталось, только AssertionError()

У меня есть тестовый модуль в стандартном формате unittest

class my_test(unittest.TestCase):

    def test_1(self):
        [tests]

    def test_2(self):
        [tests]
  etc....

В моей компании есть проприетарный тестовый жгут, который будет выполнять мой модуль в виде командной строки script, и который будет улавливать любые ошибки, возникающие в моем модуле, но требует, чтобы мой модуль был отключен в случае успеха.

Итак, я пытаюсь найти способ запустить мой тестовый модуль голым, так что если все мои тесты пройдут, на экран ничего не будет напечатано, и если тест завершится неудачно с AssertionError, эта ошибка будет передана по стандарту Python (как и любая другая ошибка в обычном Python script.)

docs защищать, используя функцию unittest.main() для запуска всех тестов в данном модуле, например

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

Проблема заключается в том, что это обертывает результаты теста в unittest harness, так что даже если все тесты успешны, он все равно печатает некоторый пух на экране, а если есть ошибка, он не просто сбрасывается, как обычная ошибка python, но также одеты в упряжи.

Я попытался перенаправить вывод на альтернативный поток, используя

with open('.LOG','a') as logf:
    suite = unittest.TestLoader().loadTestsFromTestCase(my_test)
    unittest.TextTestRunner(stream = logf).run(suite)

Проблема заключается в том, что ВСЕГДА попадает в файл журнала (включая все уведомления об ошибках). Поэтому, когда моя компания работает с модулем, она завершается успешно, потому что, насколько возможно, ошибки не возникали (потому что все они были отправлены в файл журнала).

Любые предложения о том, как я могу построить тестовый бегун, который подавляет весь пух, и пропускает ошибки через обычный стек ошибок Python? Как всегда, если вы считаете, что есть лучший способ подойти к этой проблеме, сообщите мне.

EDIT:

Вот что я решил использовать для решения этой проблемы. Во-первых, я добавил метод get_test_names() в мой тестовый класс:

class my_test(unittest.TestCase):
  etc....
    @staticmethod
    def get_test_names():
        """Return the names of all the test methods for this class."""
        test_names = [ member[0] for memeber in inspect.getmembers(my_test)
                       if 'test_' in member[0] ]

Затем я заменил свой вызов на unittest.main() следующим текстом:

# Unittest catches all errors raised by the test cases, and returns them as 
# formatted strings inside a TestResult object. In order for the test 
# harness to catch these errors they need to be re-raised, and so I am defining 
# this CompareError class to do that. 
# For each code error, a CompareError will be raised, with the original error 
# stack as the argument. For test failures (i.e. assertion errors) an 
# AssertionError is raised.
class CompareError(Exception):
    def __init__(self,err):
        self.err = err
    def __str__(self):
        return repr(self.err)

# Collect all tests into a TestSuite()
all_tests = ut.TestSuite()
for test in my_test.get_test_names():
    all_tests.addTest(my_test(test))
# Define a TestResult object and run tests
results = ut.TestResult()
all_tests.run(results)
# Re-raise any script errors
for error in results.errors:
    raise CompareError(error[1])
# Re-raise any test failures 
for failure in results.failures:
    raise AssertionError(failure[1])
4b9b3361

Ответ 1

Я придумал это. Если вы можете изменить командную строку, вы можете удалить внутреннюю переадресацию io.

import sys, inspect, traceback

# redirect stdout,
# can be replaced by testharness.py > /dev/null at console
class devnull():
    def write(self, data):
        pass

f = devnull()
orig_stdout = sys.stdout
sys.stdout = f

class TestCase():
    def test_1(self):
        print 'test_1'

    def test_2(self):
        raise AssertionError, 'test_2'

    def test_3(self):
        print 'test_3'


if __name__ == "__main__":
    testcase = TestCase()
    testnames =  [ t[0] for t in inspect.getmembers(TestCase)
                        if t[0].startswith('test_') ]

    for testname in testnames:
        try:
            getattr(testcase, testname)()
        except AssertionError, e:
            print >> sys.stderr, traceback.format_exc()

# restore
sys.stdout = orig_stdout