Я использую этот диспетчер контекста для захвата вывода. В конечном итоге он использует ту же технику, что и некоторые другие ответы, путем временной замены sys.stdout
. Я предпочитаю диспетчер контекста, потому что он объединяет всю бухгалтерию в одну функцию, поэтому мне не нужно переписывать какой-либо окончательный код, и мне не нужно писать функции настройки и удаления только для этого.
import sys
from contextlib import contextmanager
from StringIO import StringIO
@contextmanager
def captured_output():
new_out, new_err = StringIO(), StringIO()
old_out, old_err = sys.stdout, sys.stderr
try:
sys.stdout, sys.stderr = new_out, new_err
yield sys.stdout, sys.stderr
finally:
sys.stdout, sys.stderr = old_out, old_err
Используйте это так:
with captured_output() as (out, err):
foo()
# This can go inside or outside the `with` block
output = out.getvalue().strip()
self.assertEqual(output, 'hello world!')
Кроме того, поскольку исходное состояние вывода восстанавливается при выходе из with
блока, мы можем настроить второй блок захвата в той же функции, что и первый, что невозможно с использованием функций настройки и разрыва, и становится многословным при написании try-finally блоки вручную. Эта возможность пригодилась, когда целью теста было сравнение результатов двух функций относительно друг друга, а не с некоторым заранее вычисленным значением.
with mock.patch('sys.stdout', new_callable=StringIO.StringIO):
pypi.python.org/pypi/mock