Почему декоратор в Pytest не сохраняет логи в файл?

Всем привет! У меня есть декоратор, который записывает логи работы переданной функции в файл, если указано имя файла. Он работает корректно при запуске через main, но при написании теста и его выполнении декоратор не записывает данные в файл. Можете объяснить, в чем может быть проблема? Код теста приведен ниже: <br/> <pre><code class="python">import tempfile
import os
import pytest
import logging

from src.decorators import log


def test_decorator_log_not_error_rec_file(caplog):
    # Тестирование с временным файлом
    custom_dir = os.path.abspath("../logs")
    with tempfile.NamedTemporaryFile(dir=custom_dir, delete=False, mode="w") as temp_file:
        filename = temp_file.name
        file_name_for_decorator = os.path.basename(filename)

    @log(filename=file_name_for_decorator)
    def get_func_to_log(func, *args, **kwargs):
        return func(*args, **kwargs)

    def summ_(a, b):
        return a + b

    get_func_to_log(summ_, 2, 4)</code></pre>
  • 21 марта 2025 г. 13:25
Ответы на вопрос 2
Проблема с декоратором, который не записывает логи в файл во время тестирования с `pytest`, может возникать по нескольким причинам. Основные моменты, на которые следует обратить внимание:

1. **Контекст выполнения декоратора**: Возможно, ваш декоратор логирования использует глобальные или статические ресурсы, которые не инициализируются должным образом в тестовом окружении.

2. **Путь к файлу для логирования**: Убедитесь, что путь к файлу, который создает `tempfile.NamedTemporaryFile`, корректен и доступен. В тестах может не быть прав на запись в папку, где вы пытаетесь создать лог-файл.

3. **Механизм логирования**: Проверьте, как вы настраиваете логирование в вашем декораторе. Для захвата логов с помощью `caplog` в pytest, можно сразу настраивать уровни логирования и конфигурацию.

4. **Отложенное создание файла**: Временные файлы, созданные с помощью `NamedTemporaryFile`, могут быть закрыты сразу после выхода из блока `with`, в результате чего логирование может не произойти. Следует использовать опцию `delete=False` и вручную закрывать файл в конце теста.

Вот как можно изменить ваш код:

```python
import tempfile
import os
import pytest
import logging

from src.decorators import log

# Настройка логирования в начале
logging.basicConfig(level=logging.INFO)

def test_decorator_log_not_error_rec_file(caplog):
    # Тестирование с временным файлом
    custom_dir = os.path.abspath("../logs")
    os.makedirs(custom_dir, exist_ok=True)  # Убедимся, что директория существует
    with tempfile.NamedTemporaryFile(dir=custom_dir, delete=False, mode="w") as temp_file:
        filename = temp_file.name

    @log(filename=filename)  # Используйте полный путь к файлу
    def get_func_to_log(func, *args, **kwargs):
        return func(*args, **kwargs)

    def summ_(a, b):
        return a + b

    # Вызываем задекорированную функцию
    result = get_func_to_log(summ_, 2, 4)
    
    # Проверяем запись логов
    with open(filename, 'r') as log_file:
        content = log_file.read()
        assert "Expected log content" in content  # Замените на ваше ожидаемое содержимое лога

    os.remove(filename)  # Удаляем файл после теста
```

Заключительные моменты:
- Проверьте, чтобы декоратор корректно обрабатывал запись логов.
- Убедитесь, что лог-файл не удаляется до тех пор, пока логи не были записаны и соединения не закрыты.
- Используйте `os.path.join` для управления путями к файлам.

Попробуйте внести эти изменения и посмотрите, будет ли логирование работать в контексте ваших тестов.
with tempfile.NamedTemporaryFile(dir=custom_dir, delete=False, mode="w") as temp_file:

Немедленно по выходу из with файл закроется, и будет удалён.
Похожие вопросы