pytestテスト内のロギング


94

いくつかの状態変数を調べるために、テスト関数内にいくつかのロギングステートメントを配置したいと思います。

次のコードスニペットがあります。

import pytest,os
import logging

logging.basicConfig(level=logging.DEBUG)
mylogger = logging.getLogger()

#############################################################################

def setup_module(module):
    ''' Setup for the entire module '''
    mylogger.info('Inside Setup')
    # Do the actual setup stuff here
    pass

def setup_function(func):
    ''' Setup for test functions '''
    if func == test_one:
        mylogger.info(' Hurray !!')

def test_one():
    ''' Test One '''
    mylogger.info('Inside Test 1')
    #assert 0 == 1
    pass

def test_two():
    ''' Test Two '''
    mylogger.info('Inside Test 2')
    pass

if __name__ == '__main__':
    mylogger.info(' About to start the tests ')
    pytest.main(args=[os.path.abspath(__file__)])
    mylogger.info(' Done executing the tests ')

次の出力が得られます。

[bmaryada-mbp:/Users/bmaryada/dev/platform/main/proto/tests/tpch $]python minitest.py
INFO:root: About to start the tests 
======================================================== test session starts =========================================================
platform darwin -- Python 2.6.2 -- pytest-2.0.0
collected 2 items 

minitest.py ..

====================================================== 2 passed in 0.01 seconds ======================================================
INFO:root: Done executing the tests 

'__name__ == __main__'ブロックからのログメッセージのみがコンソールに送信されることに注意してください。

pytestテストメソッドからコンソールにログを強制的に送信する方法はありますか?


3
あなたは見てかかることがあります。この答えpy.testの作成者によって投稿さを、。彼は、高度な汎用性を提供するpytestプラグインを提案しています。
chb 2013

回答:


30

私のために働きます、これが私が得る出力です:[snip->例は正しくありませんでした]

編集:-sstdoutをキャプチャしないように、オプションをpy.testに渡す必要があるようです。ここ(py.testはインストールされていません)では、を使用するだけで十分でした python pytest.py -s pyt.py

あなたのコードのために、あなたが必要とするすべては渡すことです-sargsmain

 pytest.main(args=['-s', os.path.abspath(__file__)])

出力のキャプチャについては、py.testのドキュメントを参照してください。


ごめんなさい。急いでコードを貼り付けました。「問題」に気付くために、「test_one」関数から「assert 0 == 1」を削除してください。何らかの失敗(誤ったアサートを強制した)がある場合にのみ、py.testはログ情報を出力するようです。
スーパーセレクター2011年

問題ありません。プログラムによる方法を探して、コマンドラインで修正する方法を見つけました。
tryPyPy 2011年

1
デフォルトの暗黙的なstderrの代わりに、ログ出力をファイルにリダイレクトすることもできます。
hpk42 2011年

@ superselectorhpk42はpy.testの人です。聞いてください。IIUC、あなたのコードではそうなるでしょうlogging.basicConfig(filename="somelog.txt", level=logging.DEBUG)
tryPyPy 2011年

128

バージョン3.3以降、pytestライブロギングをサポートします。つまり、テストで出力されたすべてのログレコードがすぐに端末に出力されます。この機能は、ライブログセクションに記載されています。ライブロギングはデフォルトで無効になっています。有効にするにlog_cli = 1は、pyproject.toml1またはpytest.ini2構成で設定します。ライブロギングは、端末とファイルへの送信をサポートしています。関連するオプションにより、レコードのカスタマイズが可能になります。

ターミナル:

  • log_cli_level
  • log_cli_format
  • log_cli_date_format

ファイル:

  • log_file
  • log_file_level
  • log_file_format
  • log_file_date_format

log_cliフラグはコマンドラインから渡すことはできず、で設定する必要ありますpytest.ini。他のすべてのオプションは、コマンドラインから渡すことも、構成ファイルで設定することもできます。によって指摘ケビンバレこのコメントを介して行うことができ、コマンドラインからのiniオプションをオーバーライドし、-o/--overrideオプション。したがって、で宣言する代わりlog_clipytest.ini、次のように呼び出すことができます。

$ pytest -o log_cli=true ...

デモンストレーションに使用される簡単なテストファイル:

# test_spam.py

import logging

LOGGER = logging.getLogger(__name__)


def test_eggs():
    LOGGER.info('eggs info')
    LOGGER.warning('eggs warning')
    LOGGER.error('eggs error')
    LOGGER.critical('eggs critical')
    assert True

ご覧のとおり、追加の構成は必要ありません。コマンドラインでpytest指定された、pytest.iniまたはコマンドラインから渡されたオプションに基づいて、ロガーを自動的にセットアップします。

ターミナル、INFOレベル、ファンシー出力へのライブロギング

構成pyproject.toml

[tool.pytest.ini_options]
log_cli = true
log_cli_level = "INFO"
log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)"
log_cli_date_format = "%Y-%m-%d %H:%M:%S"

レガシーと同じ構成pytest.ini

[pytest]
log_cli = 1
log_cli_level = INFO
log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
log_cli_date_format=%Y-%m-%d %H:%M:%S

テストの実行:

$ pytest test_spam.py
=============================== test session starts ================================
platform darwin -- Python 3.6.4, pytest-3.7.0, py-1.5.3, pluggy-0.7.1 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-4673373, inifile: pytest.ini
collected 1 item

test_spam.py::test_eggs
---------------------------------- live log call -----------------------------------
2018-08-01 14:33:20 [    INFO] eggs info (test_spam.py:7)
2018-08-01 14:33:20 [ WARNING] eggs warning (test_spam.py:8)
2018-08-01 14:33:20 [   ERROR] eggs error (test_spam.py:9)
2018-08-01 14:33:20 [CRITICAL] eggs critical (test_spam.py:10)
PASSED                                                                        [100%]

============================= 1 passed in 0.01 seconds =============================

ターミナルとファイルへのライブロギング、ターミナルのメッセージとCRITICALレベルのみ、pytest.logファイルの派手な出力

構成pyproject.toml

[tool.pytest.ini_options]
log_cli = true
log_cli_level = "CRITICAL"
log_cli_format = "%(message)s"

log_file = "pytest.log"
log_file_level = "DEBUG"
log_file_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)"
log_file_date_format = "%Y-%m-%d %H:%M:%S"

レガシーと同じ構成pytest.ini

[pytest]
log_cli = 1
log_cli_level = CRITICAL
log_cli_format = %(message)s

log_file = pytest.log
log_file_level = DEBUG
log_file_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
log_file_date_format=%Y-%m-%d %H:%M:%S

試運転:

$ pytest test_spam.py
=============================== test session starts ================================
platform darwin -- Python 3.6.4, pytest-3.7.0, py-1.5.3, pluggy-0.7.1 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-4673373, inifile: pytest.ini
collected 1 item

test_spam.py::test_eggs
---------------------------------- live log call -----------------------------------
eggs critical
PASSED                                                                        [100%]

============================= 1 passed in 0.01 seconds =============================

$ cat pytest.log
2018-08-01 14:38:09 [    INFO] eggs info (test_spam.py:7)
2018-08-01 14:38:09 [ WARNING] eggs warning (test_spam.py:8)
2018-08-01 14:38:09 [   ERROR] eggs error (test_spam.py:9)
2018-08-01 14:38:09 [CRITICAL] eggs critical (test_spam.py:10)

1 pyproject.tomlはバージョン6.0以降でサポートされており、IMOに最適なオプションです。参照PEP 518を仕様のため。

2セクションの下で構成することもできますがpytest、カスタムのライブロギング形式を提供する場合は、構成するように誘惑されないでください。読み取りの他のツールは、文字列補間のようなものを扱い、失敗する可能性があります。とにかく使用するのが最善の選択ですが、従来のiniスタイル形式を使用せざるを得ない場合は、エラーを回避するために固執してください。setup.cfg[tool:pytest]setup.cfg%(message)spyproject.tomlpytest.ini


21
pytest.iniに含まlog_cliれている必要があるメモについては、オプションを使用してコマンドラインから値を上書きできるようです。私のために働きます。-opytest -o log_cli=true --log-cli-level=DEBUG
ケビン・バレ

@KévinBarré非常に素晴らしいコメントと一般的に非常に役立つヒント、ありがとう!答えを更新しました。
2018

ロギングを使用する場合、これは間違いなく正しい答えです。テスト内にあるログと、テスト対象のシステム内にあるログを区別するのが好きですが、これらは別々に検討する必要があります。
CMCDragonkai

@CMCDragonkaiは残念ながら、pytestその点でいくらか制限されています。ただし、これは、アプリでのテスト用の特別なログ構成で実行できるはずです。ロガーの伝播をオフにし、指定されたファイルにログを記録する「テストハンドラー」を追加します。このように、pytestカスタムハンドラーがSuTログを処理する間、テストからのレコードのみをログに記録します。
ホーフリング

1
@OfekAgmonpytest出力を保存する場合は、--result-log引数を使用できます(非推奨ですが、代替手段は次のとおりです)。pytestただし、出力とライブログ出力を同じファイルに保存することはできません。
ホーフリング
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.