#python #python-2.7 #pytest
#python #python-2.7 #pytest
Вопрос:
Досадно, что кто-то в моей компании написал библиотеку, полную функций, которые записывают данные в стандартный вывод. Мне нужно захватить и использовать эти данные, поэтому я написал это.
def capture_output(f):
orig_stdout = sys.stdout
sys.stdout = StringIO()
f()
output = sys.stdout.getvalue()
sys.stdout.close()
sys.stdout = orig_stdout
return output
Редактировать: это не для тестирования. Мне нужно вызвать метод, который печатает кучу данных в стандартный вывод и получает эти данные в виде строки (фактически не печатая ее). Это цель capture_output
метода. Я не могу использовать capsys
, потому что это бизнес-логика, а не тестовая логика.
Вот мой модульный тест для этого.
def test_capture_output(self):
output = temp_logger.capture_output(lambda: print('Hello'))
assert output == 'Hellon'
Все хорошо (тест проходит), пока я вызываю pytest следующим образом:
pytest path/to/test.py
но если я назову это так:
pytest
который запускает все наши тесты, мой тест прерывается.
______________________________________________________________________________ TestTempLogger.test_capture_output ______________________________________________________________________________
self = <test_temp_logger.TestTempLogger testMethod=test_capture_output>
def test_capture_output(self):
output = temp_logger.capture_output(lambda: print('Hello'))
> assert output == 'Hellon'
E AssertionError: assert '' == 'Hellon'
E Hello
ppt/tests/tools/FIOLauncher/dependencies/test_temp_logger.py:35: AssertionError
------------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------------
Hello
Я предполагаю, что это как-то связано с тем, как pytest фиксирует данные, записанные в стандартный вывод, но я не понимаю, почему он будет вести себя по-разному в зависимости от того, как я его вызываю. Я также не смог найти никакого обходного пути для этого.
Кто-нибудь знает, что здесь происходит?
Я использую pytest 4.6.10 (последнюю версию, к которой у меня есть доступ) и python 2.7.18 (к сожалению).
Комментарии:
1. у pytest есть
capsys
приспособление, которое уже делает это.2. «… которые записывают данные в стандартный вывод» Ну, это цель стандартного вывода.
3. @wim 1, просто используйте приспособление; это то, для чего это нужно, и нет никакой пользы от попыток точно выяснить, как попытка ручного развертывания решения мешает встроенному.
4. Можете ли вы показать, как прерываются тесты? Я предполагаю, что что-то сброшено неправильно, но не знаю, что это такое. Кстати, было бы лучше использовать
try/finally
в вашей функции, чтобы гарантировать, чтоstdout
всегда восстанавливается. @wim — вопрос заключается в тестировании функции, которая перенаправляетstdout
, а не в выполнении этого в тесте.5. @wim цель
capture_stdout
не для тестирования. Мне нужно получить вывод функции, которая печатает в стандартный вывод в виде строки как часть моей бизнес-логики. Но у меня есть тест, чтобы убедиться, что он работает, и это то, что ломается.
Ответ №1:
Оказывается, это был другой тест, в котором была эта строка.
sys.modules['sys'] = MagicMock()
вздох
и вот что самое интересное, тесты отлично работают без этого.