У меня есть тестовый модуль в стандартном формате 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])