Какие особенности написания приложения обеспечивают автоматическое тестирование и уменьшают ложные срабатывания
Что проверяют
Понимаете ли вы, что стабильность тестов закладывается в коде приложения, а не чинится ретраями в CI. Следом обычно просят рассказать про последний нестабильный тест, который вы разбирали, и что оказалось причиной.
Как отвечать
Ложные срабатывания бывают двух видов: тест падает без бага (флаки) и тест зелёный при сломанной функции. От обоих защищают одни и те же свойства кода:
- доступная разметка: тест ищет элемент по роли и имени,
getByRole('button', { name: 'Сохранить' })в Testing Library и Playwright, для остальногоdata-testid. Классы из CSS Modules и Tailwind меняются при рефакторинге и роняют тесты без повода; - логика отдельно от отрисовки: расчёты, валидация и форматирование живут в чистых функциях и хуках, их проверяют юнитами без рендера;
- управляемые зависимости: время, случайность и сеть подменяются.
vi.useFakeTimers()и фиксированная дата, сеть на уровне HTTP через MSW вместо ручного мокаfetchв каждом файле; - явные состояния: у компонента есть загрузка, ошибка и данные, тест ждёт конкретное состояние через
findByTextилиexpect(locator).toBeVisible()с автоожиданием, а неwaitForTimeout(2000); - изоляция: каждый тест создаёт свои данные и сбрасывает стор, результат не зависит от порядка запуска;
- анимации: в тестовом окружении отключаются, иначе клик попадает в движущийся элемент.
Добавьте про пирамиду: основная масса проверок в юнитах и компонентных тестах, e2e только на ключевые сценарии, потому что именно они чаще всего нестабильны.
Где спотыкаются
Лечат флаки ретраями и увеличением таймаутов. Ретрай прячет гонку, а причина обычно в запросе, который тест не дождался.
Мокают всё подряд, включая собственные дочерние компоненты. Тест проходит, а связка в продакшене сломана. Мокать стоит границы: сеть, время, браузерные API.
Отвечают перечислением SOLID без привязки к фронтенду. Интервьюер ждёт конкретных приёмов: селекторы по роли, MSW, фейковые таймеры, изоляция состояния.