ログに記録されたメッセージに関するアサーションをキャプチャして作成する簡単な方法はありますnose
か?
たとえば、次のようなことができるようにしたいと思います。
cook_eggs()
assert_logged("eggs are ready!")
ロギングを通じて送信されているメッセージをチェックできるカスタムハンドラーを作成できます。BufferingHandlerは、このジョブに完全に一致します。
また、テストで、コードで使用しているロガー(など)にハンドラーをアタッチすることもできますlogging.getLogger('foo').addHandler(...)
。最終的には、テストケースのメソッドsetUp
とメソッドにハンドラーをアタッチできます。tearDown
import logging
import logging.handlers
class AssertingHandler(logging.handlers.BufferingHandler):
def __init__(self,capacity):
logging.handlers.BufferingHandler.__init__(self,capacity)
def assert_logged(self,test_case,msg):
for record in self.buffer:
s = self.format(record)
if s == msg:
return
test_case.assertTrue(False, "Failed to find log message: " + msg)
def cook_eggs():
logging.warn("eggs are ready!")
import unittest
class TestLogging(unittest.TestCase):
def test(self):
asserting_handler = AssertingHandler(10)
logging.getLogger().addHandler(asserting_handler)
cook_eggs()
asserting_handler.assert_logged(self,"eggs are ready!")
logging.getLogger().removeHandler(asserting_handler)
unittest.main()
これが「モックオブジェクト」の目的です。
後でログメッセージについてアサーションを作成できるように、ログメッセージを適切にバッファリングするモックバージョンのロギングを使用できます。
FWIWだけですが、dataladプロジェクトでは、同様の機能が必要でしたが、ログを飲み込む(場合によっては内省する)必要もありました。そこで、解決策が登場しました-swallow_logsコンテキストハンドラー:https ://github.com/datalad/datalad/blob/master/datalad/utils.py#L296 (現在はb633c9da46ab9cccde3d4767928d167a91857153)。だから今、テストでは私たちは次のようにsmthを行います
def test_swallow_logs():
lgr = logging.getLogger('datalad')
with swallow_logs(new_level=9) as cm:
eq_(cm.out, '')
lgr.log(8, "very heavy debug")
eq_(cm.out, '') # not even visible at level 9
lgr.log(9, "debug1")
eq_(cm.out, 'debug1\n') # not even visible at level 9
lgr.info("info")
eq_(cm.out, 'debug1\ninfo\n') # not even visible at level 9