
pytestで標準出力とログ出力をテストする
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部の夏目です。
Lambdaでは標準出力に出力された内容がCloudWatch Logsにログとして出力されます。
標準出力の内容やログについてもテストしたいことは、まれによくあると思います。
そこで今回はpytestで標準出力やログ出力をテストしてみたいと思います。
標準出力
import sys
def put_out():
    print('aaa')
    print('bbb')
def test_pass(capfd):
    put_out()
    out, err = capfd.readouterr()
    assert out == 'aaa\nbbb\n'
    assert err is ''
def put_err():
    sys.stderr.write('aaa')
    sys.stderr.write('bbb')
def test_err(capfd):
    put_err()
    out, err = capfd.readouterr()
    assert out == ''
    assert err == 'aaabbb'
pytestの組み込みfixtureであるcapfdを使って標準出力の内容を取得する。
標準出力の他に標準エラー出力も取得できる
ログ
from logging import INFO, ERROR, getLogger
logger = getLogger('test')
def put():
    logger.debug('debug', extra={'additionaldata': 'debug'})
    logger.info('info', extra={'additionaldata': 'info'})
    logger.error('error', extra={'additionaldata': 'error'})
def test_log_01(caplog):
    caplog.set_level(ERROR)
    put()
    assert [('test', ERROR, 'error')] == caplog.record_tuples
    assert caplog.records[0].additionaldata == 'error'
def test_log_02(caplog):
    caplog.set_level(INFO)
    put()
    assert [('test', INFO, 'info'), ('test', ERROR, 'error')] == caplog.record_tuples
    assert caplog.records[0].additionaldata == 'info'
    assert caplog.records[1].additionaldata == 'error'
ログ出力を取得するのにはpytestの組み込みfixtureであるcaplogを使う。
set_levelメソッドでログレベルを設定し、record_tuplesもしくはrecordsでログの内容を取得する。
record_tuplesでは(logger_name, level, message)のタプルの配列としてデータが格納されている。
recordsではLogRecordオブジェクトの配列としてデータが格納されている。
そのため、 extraで渡した内容も取得できる。
まとめ
以上、pytestで標準出力とログのテストをする方法でした。
loggerで色々な情報を残そうとすると、複雑な処理が含まれてログ出力のテストが必要になったりして、これが非常に便利でした。











