在单元测试期间禁用 python 日志记录

disable python logging during unittest

我正在开发一个项目,每次 运行 时都会创建不同的日志文件。我有一些单元测试来测试我的代码,但在此过程中也会导致创建日志文件。我的应用程序代码如下所示:

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

我的测试代码是这样的:

import unittest
from module import TestRun

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

每次我 运行 都会创建单元测试文件。有没有办法在 运行 进行单元测试时禁用它。我尝试在 def setUp(self) 中设置日志级别,但没有成功。

我看到了两种处理方法:要么删除处理程序,要么一开始就不要创建它。

首先,从 test_function 中的记录器中删除处理程序:

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

这是非常暴力的方法(它删除了 所有 的日志处理程序,因此请小心使用),但它应该可以解决问题。

第二种方法是通过向 TestRun.__init__ 添加关键字参数来控制是否首先生成日志,例如:

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)

然后,当您在测试中创建实例时,执行 tr = TestRun(file_logs = False).

另一方面,正如评论中所指出的,最好只是像往常一样简单地创建日志,然后在测试完成后删除它们。

这应该可以解决问题:

logging.getLogger(__name__).disabled = True

在导入后立即添加此行。

这里有一个 context manager 将禁用部分代码的特定记录器:

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

然后您可以像这样使用它:

class MyTest(unittest.TestCase):

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