9

ロガーからの出力が実際に期待する形式(つまり、logging.basicConfig()の呼び出しによって設定される)であることをテストするユニットテストをPythonでどのように作成できますか?カスタムStreamHandlerと「re」ライブラリの使用に沿って考えていますが、StreamHandler.emit()に渡されたLogRecordが出力される文字列を提供できるようには見えません。

4

2 に答える 2

7

ドキュメント(http://packages.python.org/testfixtures/logging.html)から:

これを支援するために、TestFixturesを使用すると、Pythonのロギングフレームワークへの呼び出しの出力を簡単にキャプチャして、期待どおりであることを確認できます。作成するテストのタイプに応じて、3つの異なる手法があります。

  1. コンテキストマネージャー
  2. デコレータ
  3. 手動使用

例はドキュメントに含まれています。短縮版は以下の通りです。

コンテキストマネージャー

>>> import logging
>>> from testfixtures import LogCapture
>>> with LogCapture() as l:
...     logger = logging.getLogger()
...     logger.info('a message')
...     logger.error('an error')

その後、ログが等しいかどうかを確認できます。

>>> l.check(
...     ('root', 'INFO', 'a message'),
...     ('root', 'ERROR', 'another error'),
...     )
Traceback (most recent call last):
 ...
AssertionError: Sequence not as expected:

same:
(('root', 'INFO', 'a message'),)

first:
(('root', 'ERROR', 'another error'),)

second:
(('root', 'ERROR', 'an error'),)

デコレータ

前と同様ですが、特定の機能に適用されます。

from testfixtures import log_capture

@log_capture()
def test_function(l):
    logger = logging.getLogger()
    logger.info('a message')
    logger.error('an error')

    l.check(
        ('root', 'INFO', 'a message'),
        ('root', 'ERROR', 'an error'),
        )

手動使用

>>> from testfixtures import LogCapture
>>> l = LogCapture()

その後、ログを「チェック」することもできます。

>>> l.check(('root', 'INFO', 'a message'))
<...>

編集:特定のログにアクセスしてカスタムの方法で分析するには、繰り返し処理してl.records(ここでlは、インスタンスだけですLogCapture)、各ログのいくつかのプロパティにアクセスできます(たとえばmsg、ロガーに送信されたメッセージをlevelname含み、レベルのコードネームを含みます、そして他にもたくさんのプロパティがあります)。

于 2012-06-22T23:31:57.753 に答える
1

標準ライブラリのみを使用する場合は、このソリューションが役立ちます。unittestこれは、mockライブラリに基づいています。

たとえばscript.py、次のコンテンツがある場合。

logger = logging.getLogger(__name__)

def log_something():
    logger.debug("something")

次のようなテストを作成できます。

import unittest

import mock

from script import log_something

@mock.patch("script.logger")
def test_function(mock_log):
    log_something()

    assertTrue(
        "something" in mock_log.debug.call_args_list[0][0][0]
    )

これは、ライブラリのcall_args_listmockを使用しています。

[0][0][0]最後に説明するには:

  1. はオブジェクトcall_args_listのリストで、次のようになります。したがって、最初は最初のオブジェクトを返します。call[call("something")][0]call

  2. 2番目は、オブジェクト[0]の引数のタプルを返します。callこのようになります("something",)

  3. Thirdは、この場合[0]に与えられた最初の引数を返しますlogger。したがって、最終的な文字列は。のみになります"something"

于 2019-02-26T13:55:26.697 に答える