Какие типы данных относятся к мутабельным, а какие к немутируемым
Что проверяют
Понимаете ли вы, как изменяемость влияет на тестовые данные: общие фикстуры, параметры по умолчанию, копии объектов. У QA-автоматизатора следом обычно спрашивают, откуда берутся тесты, которые падают только в общем прогоне.
Как отвечать
Базовое деление в Python, основном языке автотестов:
- неизменяемые:
int,float,bool,str,tuple,frozenset,bytes,None. Любая «модификация» создаёт новый объект; - изменяемые:
list,dict,set,bytearray, экземпляры обычных классов и@dataclassбезfrozen=True.
Два уточнения отличают сильный ответ. Кортеж неизменяем поверхностно: (1, [2]) хранит ссылку на список, а список внутри можно менять, и такой кортеж уже не годится в ключ словаря. И ключом dict или элементом set может быть только хэшируемый объект, поэтому изменяемые встроенные типы туда не попадают.
Дальше связь с тестами:
- общие фикстуры: фикстура pytest со
scope="session", которая отдаёт словарь, делит его между всеми тестами, и изменение в одном ломает другой. Отдавайте копию или используйте областьfunction; - шаблоны тестовых данных:
payload = BASE_USERне копирует объект, нуженcopy.deepcopy, иначе поправленное поле уедет в следующий тест; parametrize: изменяемые объекты в параметрах тоже общие на все прогоны;- Go: если автотесты пишутся на Go, строки там неизменяемы, а присваивание среза
b := aне копирует элементы, для этого нуженcopy()илиslices.Clone. Сmapто же самое.
Где спотыкаются
Считают кортеж полностью неизменяемым и кладут в него списки как «безопасные» данные, а потом один тест меняет вложенный список и ломает соседей.
Путают copy.copy и copy.deepcopy: поверхностная копия словаря с вложенными списками по-прежнему делит эти списки с оригиналом.
Сравнивают через is вместо ==. a is b для маленьких чисел и коротких строк иногда даёт True из-за кэширования в CPython, и тест проходит локально, а на других данных падает.