unittest.mock или pytest-mock. Позволяют контролировать ввод/вывод и избежать реальных операций.Функции с побочными эффектами, такие как те, которые работают с файловой системой, базой данных или отправляют сетевые запросы, требуют особого подхода при тестировании, чтобы обеспечить изолированность и предсказуемость тестов. Вместо тестирования непосредственно реальных побочных эффектов, мы используем методы для замены (заглушки) или перенаправления этих эффектов в контролируемую среду. Вот несколько стратегий:
unittest.mock (или pytest-mock) в Python предоставляют инструменты для создания моков.
             
import unittest
from unittest.mock import patch
import my_module  # Модуль с функцией, которую мы хотим протестировать
def function_with_side_effect(filename):
    with open(filename, 'w') as f:
        f.write("Some data")
    return "File written"
class TestMyModule(unittest.TestCase):
    @patch('my_module.open', create=True)  # Заменяем встроенную функцию open моком
    def test_function_with_side_effect(self, mock_open):
        # Настраиваем поведение мока (если необходимо)
        mock_file = mock_open.return_value
        mock_file.write.return_value = None # Например, если функция возвращает результат write
        # Вызываем функцию, которую мы хотим протестировать
        result = function_with_side_effect("test.txt")
        # Проверяем, что open была вызвана с ожидаемым аргументом
        mock_open.assert_called_with("test.txt", 'w')
        # Проверяем, что метод write был вызван
        mock_file.write.assert_called_with("Some data")
        # Проверяем возвращаемое значение функции
        self.assertEqual(result, "File written")
pytest) используются для подготовки тестовой среды и данных перед выполнением теста, а также для очистки после его завершения.  Например, можно создать временный файл или базу данных, которые будут доступны только для данного теста.
               
import pytest
import os
@pytest.fixture
def temp_file():
    # Setup: Создаем временный файл
    filename = "temp_test_file.txt"
    with open(filename, "w") as f:
        f.write("Initial data")
    yield filename  # Передаем имя файла тесту
    # Teardown: Удаляем временный файл после теста
    os.remove(filename)
def test_function_using_temp_file(temp_file):
    # temp_file содержит имя временного файла
    with open(temp_file, "r") as f:
        content = f.read()
    assert content == "Initial data"
    with open(temp_file, "w") as f:
        f.write("Modified data")
    with open(temp_file, "r") as f:
        content = f.read()
    assert content == "Modified data"
def function_with_db_dependency(db_connection, data):
    # Используем db_connection для работы с базой данных
    db_connection.execute("INSERT INTO table VALUES (?)", (data,))
# В тестовом коде:
mock_db_connection = Mock()
function_with_db_dependency(mock_db_connection, "test_data")
mock_db_connection.execute.assert_called_with("INSERT INTO table VALUES (?)", ("test_data",))
pytest.mark.parametrize) позволяет запускать один и тот же тест с разными входными данными и ожидаемыми результатами, что особенно полезно для проверки различных сценариев, связанных с побочными эффектами.
        Важные соображения:
open('file.txt', 'w')).  Вместо этого используйте внедрение зависимостей или стратегии, описанные выше.Выбор конкретной стратегии зависит от сложности и контекста тестируемой функции.