蟒蛇 +鼻子:对记录的文本做出断言?

发布于 2024-10-18 21:18:53 字数 150 浏览 7 评论 0原文

是否有一些简单的方法可以使用 nose 捕获记录的消息并对其进行断言?

例如,我希望能够执行以下操作:

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

Is there some simple way of capturing and making assertions about logged messages with nose?

For example, I'd like to be able to do something like:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谎言月老 2024-10-25 21:18:53

您可以创建一个自定义处理程序,它可以检查通过日志记录发送的消息。 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()

You can create a custom handler which can check for the message being sent through logging. The BufferingHandler is a perfect match for this job.

You might also want to attach in your test the handler to any logger you are using in your code, such as logging.getLogger('foo').addHandler(...). You could eventually attach the handler in the setUp and tearDown methods of your test case.

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()
北凤男飞 2024-10-25 21:18:53

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

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

This is what "Mock Objects" are for.

You can use a mock version of logging which will properly buffer the log messages so that you can later make assertions about them.

孤者何惧 2024-10-25 21:18:53

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

Just FWIW, in datalad project we needed similar functionality but also to just swallow the logs (and possibly introspect). So here came the solution -- swallow_logs context handler: https://github.com/datalad/datalad/blob/master/datalad/utils.py#L296 (currently at b633c9da46ab9cccde3d4767928d167a91857153). So now in the test we do smth like

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文