Ответ
Глубокое копирование (deep copy) — это создание нового составного объекта (например, списка списков, словаря со вложенными словарями) и рекурсивное копирование всех объектов, найденных в исходном, делая копию полностью независимой от оригинала. Изменения во вложенных объектах оригинала не затронут копию, и наоборот.
Почему это важно в тестировании на Python?
Часто нужно подготовить тестовые данные (фикстуры), модифицировать их в тесте, но при этом сохранить исходное состояние для других тестов или для сравнения "до/после". Поверхностное копирование (copy.copy() или list()) здесь подведет.
Пример проблемы и решения:
import copy
# Исходные тестовые данные (сложная структура)
test_config_original = {
'server': {'host': 'localhost', 'port': 8080},
'users': [{'id': 1, 'role': 'admin'}, {'id': 2, 'role': 'tester'}]
}
# ПОВЕРХНОСТНОЕ копирование (опасно!)
test_config_shallow = copy.copy(test_config_original)
# ИЛИ test_config_shallow = dict(test_config_original)
# ГЛУБОКОЕ копирование (правильно для независимой копии)
test_config_deep = copy.deepcopy(test_config_original)
# Модифицируем вложенный объект в "копии"
test_config_shallow['server']['port'] = 9999 # Меняет ОРИГИНАЛ!
test_config_deep['users'][0]['role'] = 'superuser' # Не меняет оригинал
print("Original:", test_config_original['server']['port']) # 9999 (!)
print("Original user role:", test_config_original['users'][0]['role']) # 'admin' (ok)
Когда использовать deepcopy в автотестах:
- Подготовка изолированных фикстур для параметризованных тестов.
- Эмуляция состояния данных "до выполнения операции" для последующего сравнения.
- Создание модифицированных конфигов для тестирования разных сценариев на основе базового.
Минус: deepcopy работает медленнее и потребляет больше памяти, чем поверхностное копирование, поэтому для простых, одноуровневых структур оно избыточно.