Я использую этот менеджер контекста для захвата вывода.В конечном итоге он использует ту же технику, что и некоторые другие ответы, временно заменив sys.stdout
.Я предпочитаю менеджер контекста, потому что он объединяет всю бухгалтерию в одну функцию, поэтому мне не нужно переписывать какой-либо код try-finally, и мне не нужно писать функции setup и teardown только для этого.
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
, мы можем установить второй блок захвата в той же функциив качестве первого, что невозможно при использовании функций setup и teardown, и становится многословным при написании блоков try-finally вручную.Эта способность пригодилась, когда целью теста было сравнение результатов двух функций относительно друг друга, а не с каким-то предварительно вычисленным значением.