Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python + nose: make assertions about logged text?

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!")
like image 554
David Wolever Avatar asked Feb 22 '11 23:02

David Wolever


2 Answers

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()
like image 188
Rod Avatar answered Sep 29 '22 07:09

Rod


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.

like image 37
S.Lott Avatar answered Sep 29 '22 07:09

S.Lott