Python + nose:对记录的文本做出断言?

时间:2011-02-22 23:23:33

标签: python testing logging nose

是否有一些使用nose捕获和记录已记录消息的简单方法?

例如,我希望能够做到这样的事情:

cook_eggs()
assert_logged("eggs are ready!")

3 个答案:

答案 0 :(得分:12)

您可以创建一个自定义处理程序,可以检查通过日志记录发送的消息。 BufferingHandler是这项工作的完美搭档。

您可能还希望在测试中将处理程序附加到您在代码中使用的任何记录器,例如logging.getLogger('foo').addHandler(...)。您最终可以在测试用例的setUptearDown方法中附加处理程序。

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()

答案 1 :(得分:2)

这就是“模拟对象”的用途。

您可以使用模拟版本的日志记录,它将正确缓冲日志消息,以便您以后可以对它们进行断言。

答案 2 :(得分:0)

Just FWIW,在datalad项目中,我们需要类似的功能,但也只是吞下日志(可能还有内省)。所以这里出现了解决方案 - swallow_logs上下文处理程序:https://github.com/datalad/datalad/blob/master/datalad/utils.py#L296(目前在b633c9da46ab9cccde3d4767928d167a91857153)。所以现在在测试中我们会像

一样
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