Для тестирования логирования в Python с использованием мок-объектов и фикстур можно сделать следующее:
Преимущества такого подхода: изоляция тестов, возможность проверки конкретных сообщений и уровней логирования, и отсутствие зависимостей от файловой системы или других внешних ресурсов.
Тестирование логирования в Python с использованием мок-объектов и фикстур - важная часть обеспечения надежности и правильности работы приложения. Вот как это можно сделать:
Основные подходы:
Пример с использованием `unittest.mock` и `logging.handlers.StringIOHandler` (без pytest, демонстрирует основные принципы):
import unittest
import logging
import logging.handlers
from unittest.mock import patch
class MyClass:
    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)
    def do_something(self, value):
        self.logger.info(f"Doing something with value: {value}")
        if value < 0:
            self.logger.error("Value cannot be negative")
            return False
        return True
class TestMyClass(unittest.TestCase):
    def test_do_something_logs_info(self):
        # Создаем обработчик, который пишет в строку
        log_stream = logging.handlers.StringIOHandler()
        logger = logging.getLogger('test_logger') # Используем отдельный logger, чтобы избежать влияния на глобальный
        logger.setLevel(logging.INFO)
        logger.addHandler(log_stream)
        # Инстанцируем класс, передавая ему logger
        my_object = MyClass(logger=logger)
        my_object.do_something(10)
        # Проверяем, что в лог было записано ожидаемое сообщение
        self.assertIn("Doing something with value: 10", log_stream.getvalue())
    def test_do_something_logs_error_when_negative(self):
        log_stream = logging.handlers.StringIOHandler()
        logger = logging.getLogger('test_logger_error')
        logger.setLevel(logging.ERROR) #устанавливаем уровень логирования, иначе INFO не будет писать в ERROR
        logger.addHandler(log_stream)
        my_object = MyClass(logger=logger)
        my_object.do_something(-5)
        self.assertIn("Value cannot be negative", log_stream.getvalue())
if __name__ == '__main__':
    unittest.main()
  Пример с использованием `pytest` и `caplog`:
import logging
import pytest
class MyClass:
    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)
    def do_something(self, value):
        self.logger.info(f"Doing something with value: {value}")
        if value < 0:
            self.logger.error("Value cannot be negative")
            return False
        return True
def test_do_something_logs_info(caplog):
    caplog.set_level(logging.INFO)
    my_object = MyClass()
    my_object.do_something(10)
    assert "Doing something with value: 10" in caplog.text
def test_do_something_logs_error_when_negative(caplog):
    caplog.set_level(logging.ERROR)
    my_object = MyClass()
    my_object.do_something(-5)
    assert "Value cannot be negative" in caplog.text
  Пояснения:
Плюсы использования моков и фикстур:
Рекомендации: