Gernar
Frontend DeveloperТестирование

Интервью-вопрос

Что такое Unit-тестирование

Объясните unit-тестирование как проверку небольшой единицы поведения в изоляции. Покажите, что понимаете пользу, ограничения и frontend-риски: состояние UI, асинхронность, моки и границы теста.

Добавлен
Редакция

Подготовьте короткий ответ и пару деталей на случай уточняющих вопросов.

🐰0
🥚0

Мини-квиз

Проверка перед разбором

Несколько быстрых вопросов перед разбором. Так проще поймать места, которые только кажутся понятными.

Вопрос 1 из 40 правильно

Граница unit-теста

Что лучше ответить, если вас просят коротко отличить unit-тест от интеграционного теста во frontend?

Варианты ответа

Разбор

Разобраться, а не зазубрить

Дальше разбираем суть, типичные уточнения и места, где легко сказать лишнее или перепутать термины.

Базовая идея

Unit-тестирование проверяет небольшую единицу поведения отдельно от остальной системы. В ответе не нужно спорить о том, что именно считать unit во всех проектах. Лучше сказать практично: это может быть функция, модуль, хук, редьюсер или компонент, если вы контролируете его зависимости и проверяете конкретное поведение.

Удобная устная формулировка: unit-тест отвечает на вопрос, получу ли я ожидаемый результат, если дам этой части кода известные входные данные и контролируемые зависимости.

Что именно считается unit во frontend

Во frontend unit не всегда равен одной функции. Простая функция форматирования цены подходит идеально. Хук можно тестировать как единицу логики состояния. Компонент можно тестировать как unit, если вы изолируете внешние зависимости и проверяете его наблюдаемое поведение: что показано пользователю, какие элементы доступны с клавиатуры, какие labels связаны с полями и что происходит после действия.

Не стоит говорить, что unit-тесты это только тесты на чистые функции. Для учебного примера такая фраза подходит, но для React и Next.js практики она слишком узкая. В реальном интерфейсе ошибки часто появляются в ветвлениях, состояниях загрузки, обработке ошибок и повторных действиях пользователя.

Контракт хорошего unit-теста

Хороший unit-тест обычно держится на трех вещах.

  • Изоляция. Тест не ходит в реальную сеть, не зависит от текущего времени, порядка запуска и состояния браузера.
  • Повторяемость. Один и тот же код с теми же входными данными дает тот же результат.
  • Проверка поведения. Тест проверяет результат, видимый эффект или контракт функции, а не внутреннюю раскладку переменных.

Если вас спрашивают про инструменты, можно назвать Jest, Vitest, React Testing Library или похожий стек. Но не превращайте ответ в список библиотек. На интервью обычно проверяют не названия фреймворков, а понимание того, что именно и зачем вы проверяете.

Главная ловушка ответа

Самая частая слабость ответа: unit-тест проверяет одну функцию. Это не совсем ошибка, но формулировка слишком узкая. Во frontend важна граница поведения. Например, компонент может показывать spinner, потом список, потом ошибку после неуспешного запроса. Unit-тест такого компонента не обязан обращаться к реальному API. Он должен контролировать ответ зависимости и проверять, что UI корректно переходит между состояниями.

Еще одна ловушка состоит в том, чтобы мокать все подряд. Если вы замокали и внешний API, и саму функцию расчета, тест больше не проверяет полезную логику. Моки нужны на границах: сеть, время, навигация, хранилище, browser-only API. Проверяемую часть лучше оставлять настоящей. Иначе можно получить зеленый тест, который скрывает реальный баг. Например, расчет цены не запускается после ошибки запроса, кнопка остается disabled или старый ответ перезаписывает новый список.

Практический вывод

На интервью полезно объяснить, где unit-тесты дают максимальную ценность.

  • Форматирование, валидация, расчет, сортировка и фильтрация.
  • Редьюсеры и функции обновления состояния.
  • Хуки с ветвлениями, кешированием или асинхронными переходами.
  • Компоненты, где важны disabled state, ошибка, пустой список, фокус, labels, доступная разметка и реакции на действия.
  • Регрессии, которые уже ломались и должны быть зафиксированы тестом.

Не обещайте покрыть unit-тестами каждую строку. Более зрелый ответ звучит так: я начинаю с критичной логики и рискованных веток, а для связки нескольких частей добавляю интеграционные тесты.

Асинхронность и UI state

Для frontend особенно важно упомянуть асинхронность. Если код получает данные, unit-тест может проверять не только успешный ответ. Часто нужно проверить loading, error, empty state, повторную отправку и защиту от устаревшего результата. Например, если пользователь быстро меняет фильтр, старый ответ не должен перезаписать новый список.

При этом реальный запрос в unit-тесте обычно не нужен. Его заменяют контролируемой зависимостью. Так тест отвечает за логику компонента, а не за доступность внешнего API или стабильность сети. Если у сценария есть retry или rollback после ошибки, это тоже лучше проверить явно. Иначе пользователь может остаться с устаревшими данными или заблокированной кнопкой.

Нестандартные случаи и ограничения

Unit-тест не доказывает, что вся страница работает в браузере так, как ожидает пользователь. Он может не поймать ошибку маршрутизации, несовпадение SSR и CSR, проблему фокуса, реальную сетевую политику, XSS из небезопасного рендера внешних данных, производительность тяжелой страницы или некорректную интеграцию с backend.

Поэтому хороший ответ должен звучать сбалансированно. Unit-тесты дают быструю и дешевую обратную связь по небольшим частям системы, но качество frontend-приложения требует нескольких уровней проверки. Unit-тесты отвечают за локальную корректность, интеграционные тесты за связку частей, e2e тесты за критичные пользовательские пути.

Частые ошибки

Где обычно ошибаются

Проверьте формулировки, которые звучат уверенно, но на интервью быстро выдают пробелы.

  1. 1

    Свести unit-тестирование только к простым функциям

    Unit-тест действительно часто проверяет чистую функцию. Но во frontend он также может проверять хук, редьюсер, форматтер, валидатор или компонент с локальным состоянием. Если вы ограничитесь примером со сложением чисел, ответ прозвучит слишком учебно.
  2. 2

    Не объяснить изоляцию

    Без изоляции тест может зависеть от сети, времени, порядка запуска или состояния браузера. Такой тест будет случайно падать и не покажет, где сломалась логика.
  3. 3

    Проверять реализацию вместо поведения

    Хрупкий тест знает слишком много про внутренние функции, имена переменных и структуру компонента. На интервью лучше говорить про результат, который видит пользователь или получает вызывающий код.
  4. 4

    Забыть про асинхронные состояния UI

    Во frontend часто ломается не сам запрос, а состояние вокруг него: индикатор загрузки, текст ошибки, пустой список, повторный клик или устаревший ответ. Если это не проверить, пользователь может увидеть старые данные, двойное списание или бесконечный loader. Безопаснее мокать источник данных и явно проверять переходы состояния.
  5. 5

    Игнорировать браузерные API и Next.js контекст

    Код, который напрямую читает window, localStorage или размер экрана во время render, может сломаться в SSR или дать mismatch при hydration. В unit-тесте лучше отделить такую зависимость оберткой, замокать ее и проверить fallback для серверного рендера.

Follow-up

Что могут спросить дальше

Короткие ответы на вопросы, которыми интервьюер проверяет понимание темы.

Живые ответы

Видео с похожим вопросом

Если найдем публичные интервью с таким вопросом, добавим их сюда. Их удобно смотреть после теории, чтобы свериться с живыми ответами.

Пока видео нет. Когда появятся подходящие публичные интервью, добавим их в этот блок, чтобы можно было сравнить разбор с тем, как отвечают реальные кандидаты.

Содержание