Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override python logging for test efficiency

In many cases unit-tests are significantly slowed down by the use of python's logging package. Assuming logging isn't essential to the test, how would you cleanly override logging per-test, so that log commands would be effectively skipped.

Assume the use of multiple loggers such as in:

logger1 = logging.getLogger('logger1')
logger2 = logging.getLogger('logger2')
like image 846
Jonathan Livni Avatar asked Aug 24 '11 08:08

Jonathan Livni


People also ask

How do I override a Python logger?

You can firstly implement your own logger class by deriving from logging. Logger, in which you override the methods you target. And then you pass the logger class to the logging system by using logging. setLoggerClass.

Does logging in Python use log4j?

The inbuilt logging module in python requires some handful of lines of code to configure log4j-like features viz - file appender, file rotation based on both time & size. For one-liner implementation of the features in your code, you can use the package autopylogger .


1 Answers

Option 1:

Logging can be disabled by calling

logging.disable(logging.CRITICAL)

and turned back on with

logging.disable(logging.NOTSET)

However, even after disabling logging, a logging statement such as logger.info would still cause Python to do a few attribute lookups and function calls before reaching the isEnabledFor method. Still, this might be good enough.

Option 2:

Use mocking:

class MockLogger(object):
    def debug(msg, *args, **kwargs): pass
    def info(msg, *args, **kwargs): pass
    def warn(msg, *args, **kwargs): pass
    def error(msg, *args, **kwargs): pass
    def critical(msg, *args, **kwargs): pass

class Test(unittest.TestCase):
    def test_func(self):
        _logger1=testmodule.logger1
        _logger2=testmodule.logger2
        testmodule.logger1=MockLogger()
        testmodule.logger2=MockLogger()
        # perform test
        testmodule.logger1=_logger1
        testmodule.logger2=_logger2

This will reduce the time consumed by logging statements to the time it takes to do one attribute lookup and one (noop) function call. If that's not satisfactory, I think the only option left is removing the logging statements themselves.

like image 130
unutbu Avatar answered Sep 28 '22 09:09

unutbu