Search code examples
pythontestingloggingnose

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!")

Solution

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