Для тестирования логирования в 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
Пояснения:
Плюсы использования моков и фикстур:
Рекомендации: