mkerins
mkerins

Reputation: 110

disable python logging during unittest

I'm working on a project that creates a different log file each time it runs. I have some unit tests that test my code but in the process also cause the log files to get created. My application code looks like this:

module.py

import logging
from uuid import uuid4

class TestRun:

    def __init__(self):
        self.test_run_id = str(uuid4())
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.INFO)
        handler = logging.FileHandler('{}.log'.format(self.test_run_id))
        self.logger.addHandler(handler)

    def prep_test_run(self):
        self.logger.info('Starting prep')

if __name__ == '__main__':
    tr = TestRun()
    tr.prep_test_run()

My test code is something like this:

import unittest
from module import TestRun

class TestModule(unittest.TestCase):
    def test_function(self):
        tr = TestRun()
        tr.prep_test_run()

Every time I run the unit tests files get created. Is there a way to disable this while running the unit tests. I've tried to set the log level in def setUp(self) but it didn't work.

Upvotes: 1

Views: 3939

Answers (3)

Nathan Villaescusa
Nathan Villaescusa

Reputation: 17629

Here's a context manager that will disable a specific logger for a portion of code:

from contextlib import contextmanager

@contextmanager
def disable_logger(name):
    """Temporarily disable a specific logger."""
    logger = logging.getLogger(name)
    old_value = logger.disabled
    logger.disabled = True
    try:
        yield
    finally:
        logger.disabled = old_value

You can then use it like so:

class MyTest(unittest.TestCase):

   def test_do_something(self):
      with disable_logger('mypackage.mymodule'):
          mymodule.do_something()

Upvotes: 2

vadimhmyrov
vadimhmyrov

Reputation: 189

This should do the trick:

logging.getLogger(__name__).disabled = True

Add this line right after your imports.

Upvotes: 0

Josh Karpel
Josh Karpel

Reputation: 2145

I see two paths for handling this: either remove the handler, or never create it in the first place.

For the first, remove the handlers from the logger in test_function:

def test_function(self):
    tr = TestRun()
    tr.logger.handlers = []

This is very brute force (it removes all of the log handlers, so use it carefully), but it should solve the problem.

The second way would be to control whether you produce the logs in the first place by adding a keyword argument to TestRun.__init__, something like:

class TestRun:
    def __init__(self, file_logs = True):
        self.test_run_id = str(uuid4())
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.INFO)
        if file_logs:
            handler = logging.FileHandler('{}.log'.format(self.test_run_id))
            self.logger.addHandler(handler)

Then, when you make a instance in your tests, do tr = TestRun(file_logs = False).

On the other hand, as pointed out in comments, it might be best to simply create the logs as normal, then delete them once the test is done.

Upvotes: 0

Related Questions