pytest でテストを実行する際、pytest-capturelog というパッケージを入れるとログを出力することができます。
(ただし出力されるのはテストが失敗した時のみ)
このとき、debug レベル以下のログは表示したくない、といった具合に
出力するログのレベルを調整できないかと思って調べてみたらできました。のでメモ。
以下手順。
pytest, pytest-capturelog のインストール
pip でインストールするのであればこう。
$ pip install pytest $ pip install pytest-capturelog
私は普段 zc.buildout でパッケージを管理しているので、
同じようにされている方はこちらのファイルを参考にしてください。
(といっても、普通にインストールしてるだけですが)
gae-django-template/buildout.cfg at master · zaki-yama-labs/gae-django-template · GitHub
テストを書く
はじめに用意したのはこのようなクラス。
test.py
# -*- coding: utf-8 -*- import logging logger = logging.getLogger(name=__name__) def test_foo(): logger.debug('log level: DEBUG') logger.info('log level: INFO') # ログ出力のためテストが失敗するように raise ValueError
これを実行すると次のようにログが出力されます。
$ py.test test.py ======================================================== test session starts ======================================================== platform darwin -- Python 2.7.5 -- py-1.4.28 -- pytest-2.7.1 rootdir: /Users/*****/pytest-capturelog-sample, inifile: plugins: capturelog collected 1 items test.py F ============================================================= FAILURES ============================================================== _____________________________________________________________ test_foo ______________________________________________________________ caplog = <pytest_capturelog.CaptureLogFuncArg object at 0x1030506d0> def test_foo(caplog): # caplog.setLevel(logging.INFO) logger.debug('log level: DEBUG') logger.info('log level: INFO') # ログ出力のためテストが失敗するように > raise ValueError E ValueError test.py:12: ValueError ----------------------------------------------------------- Captured log ------------------------------------------------------------ test.py 9 DEBUG log level: DEBUG test.py 10 INFO log level: INFO ===================================================== 1 failed in 0.01 seconds ======================================================
ログレベルを設定する
さて、本題の出力するログレベルを設定する方法ですが、
テストメソッドの引数に caplog
というパラメータが渡されてくるそうです。
この caplog
の setLevel
というメソッドを呼び出すと、そのメソッド内でのログレベルを設定できます。
先ほどの test_foo
だと、こんな感じに。
def test_foo(caplog): caplog.setLevel(logging.INFO) logger.debug('log level: DEBUG') logger.info('log level: INFO') # ログ出力のためテストが失敗するように raise ValueError
この状態で再度テストを実行すると...
======================================================== test session starts ======================================================== platform darwin -- Python 2.7.5 -- py-1.4.28 -- pytest-2.7.1 rootdir: /Users/********/pytest-capturelog-sample, inifile: plugins: capturelog collected 1 items test.py F ============================================================= FAILURES ============================================================== _____________________________________________________________ test_foo ______________________________________________________________ caplog = <pytest_capturelog.CaptureLogFuncArg object at 0x1030876d0> def test_foo(caplog): caplog.setLevel(logging.INFO) logger.debug('log level: DEBUG') logger.info('log level: INFO') # ログ出力のためテストが失敗するように > raise ValueError E ValueError test.py:12: ValueError ----------------------------------------------------------- Captured log ------------------------------------------------------------ test.py 10 INFO [INFO] log ===================================================== 1 failed in 0.01 seconds ======================================================
というわけで、INFO レベル未満のログを出力しないよう設定することができました。
(おまけ)テストクラスのメソッドとして定義していたら?
pytest-capturelog のページには書いてませんが、テストクラスのメソッドであっても caplog
は渡されてくるようです。
なので、
class TestClass(object): def test_bar(self, caplog): caplog.setLevel(logging.INFO) logger.debug('log level: DEBUG') logger.info('log level: INFO') # ログ出力のためテストが失敗するように raise ValueError
これで OK。