Visual regression testing

Как строить полезные визуальные проверки: выбирать состояния, стабилизировать окружение, разбирать diff и контролировать обновление эталонов.

Обновлено:

Содержание

Visual regression testing — сравнение текущего изображения интерфейса с согласованным эталоном. Подход помогает заметить изменения, которые легко пропустить функциональными утверждениями: перекрытую кнопку, исчезнувшую подпись, неверный отступ или обрезанный текст.

Само различие пикселей ещё не означает дефект. Шрифт мог иначе отрисоваться в другой ОС, а дата — закономерно измениться. Поэтому качество визуального теста определяется не количеством скриншотов, а тем, насколько точно он отделяет нежелательное изменение от ожидаемого и случайного.

Что считать эталоном

Baseline — сохранённое ожидаемое изображение конкретного состояния. Оно должно иметь понятное происхождение: версия приложения, данные, браузер, viewport и условия отображения. Скриншот уже сломанной страницы не становится правильным только потому, что был первым.

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

Где визуальные проверки полезнее всего

Хорошие кандидаты — стабильные компоненты и страницы, где расположение имеет значение: карточка товара, форма, диалог, письмо в web-просмотре, таблица с действиями. Особенно полезны состояния, которые редко смотрят вручную: длинная ошибка, пустой результат, disabled-кнопка, крупный текст.

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

Окружение должно быть воспроизводимым

Рендеринг зависит от браузера, ОС, шрифтов, масштаба, графических особенностей и настроек. Снимки для сравнения создавайте в согласованном окружении, с закреплёнными версиями и одинаковыми ресурсами. Перенос запуска с ноутбука на CI может потребовать отдельного набора эталонов.

Фиксируйте viewport, локаль, часовой пояс, тему, тестовую учётную запись и содержимое ответа API. Управляемое время важно для календарей и относительных дат. Если продукт поддерживает несколько тем, это осознанные варианты теста, а не случайные значения системной настройки.

Когда экран действительно готов

Завершение навигации не всегда означает готовность содержимого. Шрифт может ещё загружаться, данные — приходить отдельным запросом, а изображение — менять высоту блока. Снимок в случайный момент проверяет гонку, а не согласованное состояние.

Ждите наблюдаемого признака: появились нужные данные, исчез индикатор, загрузился конкретный ресурс. Не заменяйте это большим фиксированным sleep. Анимацию можно отключить для проверки финального состояния; если проверяется сама анимация, нужен отдельный сценарий с контролируемым моментом, а не обычный статичный baseline.

Область, маски и допустимая разница

Снимок компонента быстрее объясняет локальную проблему. Полная страница полезна для взаимного расположения разделов, но может скрывать небольшое критичное изменение среди множества пикселей. Выбор масштаба проверки связан с риском.

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

Практический пример: окно подтверждения

Пусть команда переработала общий компонент диалога. Нужно убедиться, что подтверждение удаления вмещает длинное имя объекта и сохраняет доступность кнопок.

  1. 1.Создайте фиксированную тестовую запись с длинным названием и откройте диалог. Ожидается правильный текст и отсутствие обрезки значимой информации.
  2. 2.Проверьте наличие заголовка, обеих кнопок и завершение загрузки шрифтов. Только затем снимите компонент в согласованном настольном viewport.
  3. 3.Повторите состояние в узком viewport. Ожидается доступность подтверждения и отмены без наложения блоков.
  4. 4.Измените CSS так, чтобы кнопка частично оказалась за краем, в отдельной тестовой ветке. Ожидается обнаруженный diff: это проверка полезности самого механизма.
  5. 5.Верните корректную версию и выполните повторный запуск. Ожидается стабильное сравнение без случайного падения.

Удаление выполняется на подготовленных данных. Скриншот не должен содержать чужие реальные записи и персональную информацию.

Как разбирать diff

Смотрите три изображения: expected, actual и diff. Сначала определите, изменилось содержимое, окружение или layout. Затем воспроизведите экран и установите пользовательское последствие. Один исчезнувший символ валюты может быть важнее большого декоративного отличия.

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

Что визуальный тест не доказывает

Правильная картинка не гарантирует, что кнопка нажимается, запрос содержит правильные данные, screen reader получает имя или пользователь имеет нужные права. Визуальная регрессия дополняет функциональные, доступностные и интеграционные проверки.

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

Типичные ошибки и выводы

Ошибки — снимать каждую страницу во всех комбинациях, хранить непроверенные baseline и решать шум повышением допуска. Ещё одна — ждать произвольные секунды, не контролируя данные и шрифты.

Начинайте с небольшого набора важных состояний, проверяйте стабильность и демонстрируйте, какие реальные регрессии он ловит. Полезный визуальный тест даёт понятный diff и конкретное решение: исправить продукт, подготовку окружения или согласованно обновить эталон.

Что ещё почитать