Методы тестирования, используемые ведущими командами инженеров.
Тестировать UI неудобно. Пользователи ожидают частых релизов, наполненных функциями. Но каждая новая функция — это больше пользовательского интерфейса и новых состояний, которые вам затем нужно тестировать. Каждый инструмент тестирования обещает "простоту, очевидность, быстроту", но также предлагает кучу компромиссов, которые приписаны внизу мелким шрифтом.
Как ведущие команды разработчиков фронтенда все успевают? Какова их стратегия тестирования, и какие методы они используют? Я исследовал десять команд из сообщества Storybook, чтобы узнать, что реально работает — Twilio, Adobe, Peloton, Shopify и другие.
В этой статье рассказывается о методах тестирования пользовательского интерфейса, используемых масштабными инженерными командами. Таким образом, вы сможете создать прагматичную стратегию тестирования, которая сбалансирует охват, настройку и обслуживание. Попутно мы укажем на подводные камни, которых следует избегать.
Что мы тестируем?
Все основные JavaScript-фреймворки являются компонентно-ориентированными. Это означает, что пользовательский интерфейс строится "снизу вверх", начиная с атомарных компонентов и постепенно складываясь в страницы.
Помните, каждый элемент пользовательского интерфейса теперь является компонентом. Да, это касается и страниц. Единственная разница между страницей и кнопкой заключается в том, как они потребляют данные.
Поэтому тестирование пользовательского интерфейса теперь является синонимом тестирования компонентов.
Когда речь идет о компонентах, разница между различными методами тестирования может быть нечеткой. Вместо того чтобы сосредоточиться на терминологии, давайте рассмотрим, какие характеристики пользовательского интерфейса требуют тестирования.
- Визуальные характеристики: правильно ли отрисовывается компонент с заданным набором свойств или состояний?
- Композиция: работают ли вместе несколько компонентов?
- Взаимодействие: события обрабатываются так, как задумано?
- Доступность: доступен ли пользовательский интерфейс?
- Пользовательские потоки: работают ли сложные взаимодействия между различными компонентами?
На чем следует сосредоточиться?
Комплексная стратегия тестирования пользовательского интерфейса позволяет сбалансировать усилия и ценность. Но существует так много способов тестирования, что разобраться, какой из них подходит для той или иной ситуации, может оказаться непосильной задачей. Именно поэтому многие команды оценивают различные методы тестирования, используя приведенные ниже критерии.
- 💰 Стоимость обслуживания: время и усилия, необходимые для написания и поддержки тестов.
- ⏱️ Скорость итераций: насколько быстро проходит обратная связь между внесением изменения и просмотром результата.
- 🖼 Реалистичная среда: где выполняются тесты — в реальном браузере или смоделированной среде, такой как JSDOM.
- 🔍 Устранение неполадок: тест не работает, как быстро вы можете определить источник сбоя.
- 🤒 Test Flake: ложные срабатывания / отрицательные результаты противоречат цели тестирования.
Например, сквозное тестирование имитирует "реальные" потоки пользователей, но его нецелесообразно применять повсеместно. Ключевое преимущество тестирования в веб-браузере также является недостатком. Тесты выполняются дольше, и существует больше точек отказа (flake!).
Теперь, когда мы рассмотрели характеристики пользовательского интерфейса для тестирования и критерии оценки каждого метода тестирования, давайте посмотрим, как команды разрабатывают свою стратегию тестирования.
"Тестирование дает мне полную уверенность при автоматическом обновлении зависимых элементов. Если тесты проходят успешно, мы их внедряем".
— Саймон Таггарт, главный инженер Twilio
Визуальное тестирование: хорошо ли это выглядит?
Современные интерфейсы имеют бесчисленное множество вариаций. Чем их больше, тем сложнее убедиться, что все они правильно отображаются на устройствах и в браузерах пользователей.
В прошлом вам приходилось запускать приложение, переходить на страницу и выполнять всевозможные манипуляции, чтобы привести пользовательский интерфейс в нужное состояние.
Конструкция компонента позволяет вам отображать определенную вариацию как функцию реквизитов и состояния. Вам не нужно запускать все приложение, чтобы посмотреть, как отображается компонент, вместо этого передайте реквизиты и состояние, чтобы просмотреть его в отдельности.
Twilio и Shopify используют Storybook для изоляции компонентов, имитации их вариаций и записи поддерживаемых тестовых случаев в виде "историй". Это позволяет разработчикам проверять внешний вид компонентов во время первоначальной разработки и повторно в QA (англ. Quality Assurance — обеспечение качества продукта — это, собственно, весь комплекс процессов, обеспечивающих качество. QA интегрировано во все этапы разработки: от описания проекта до тестирования, релиза и даже пост-релизного обслуживания).
Тем не менее, учитывая масштаб приложений, тестировать внешний вид пользовательского интерфейса вручную непрактично. Вам пришлось бы проверять вариации каждого компонента в каждой точке останова и в каждом браузере при каждом изменении пользовательского интерфейса. Это очень много работы!
Auth0 и Radix UI автоматизируют процесс проверки пользовательского интерфейса. Они используют визуальные тесты для получения скриншота каждого компонента пользовательского интерфейса, вместе с разметкой, стилем и другими активами, в неизменной среде браузера. Таким образом, они проверяют то, что пользователь видит на самом деле.
При каждой фиксации новые скриншоты автоматически сравниваются с ранее принятыми базовыми скриншотами. Когда машина обнаруживает визуальные различия, разработчик получает уведомление, чтобы утвердить намеренное изменение или исправить случайный баг.
Но как насчет тестирования моментальных снимков DOM ( от англ. The Document Object Model — кроссплатформенный и независимый от языка интерфейс, который рассматривает документ XML или HTML как древовидную структуру, где каждый узел — это объект, представляющий часть документа. DOM представляет документ в виде логического дерева)? Недостатки оценки большого текстового блока HTML хорошо задокументированы.
Оно того стоит?
Всегда. Визуальные тесты — это высокая ценность при низких затратах. Они требуют минимальных усилий для поддержки, выполняются в реальных браузерах и не так подвержены ошибкам.
Тестирование композиции: работают ли компоненты вместе?
При объединении компонентов происходят странные вещи. Пользовательские интерфейсы состоят из множества простых компонентов. Проверка того, как эти компоненты интегрируются, гарантирует, что система работает как единое целое.
Но тестирование композиции является сложной задачей, поскольку сложные функции часто связаны с данными и состоянием приложения. Для этого необходимо смоделировать или имитировать бизнес-логику приложения.
BBC и Sidewalk Labs (Google) используют Storybook для изолирования составных компонентов. Дополнения Storybook упрощают моделирование данных, событий и ответов API (от англ. Application Programming Interface — интерфейс прикладного программирования). После того, как ваш пользовательский интерфейс изолирован в Storybook, вы можете проводить визуальное тестирование для проверки интеграции компонентов вплоть до страниц.
Тестирование сложных компонентов в Storybook — визуализации данных, выбора даты и даже макетов целых страниц.
Оно того стоит?
Зачастую. Эти тесты требуют определенных вложений, но они выявляют неочевидные проблемы интеграции, которые трудно отследить иным способом.
Тестирование взаимодействия: что происходит, когда я нажимаю эту кнопку?
Интерфейсы не статичны. Пользователь может взаимодействовать с пользовательским интерфейсом, заполнять поля формы и создавать ситуации.
Как убедиться, что пользовательский интерфейс правильно реагирует на взаимодействие? Мы можем использовать компьютер для моделирования и проверки взаимодействия с пользователем!
Один из подходов заключается в использовании таких инструментов, как Enzyme, для доступа к внутренним методам компонентов. Затем вызвать изменения состояния и проверить результат. Это работает, но в итоге вы тестируете внутреннюю работу вместо того, чтобы взаимодействовать с пользовательским интерфейсом так, как это делал бы пользователь.
Именно поэтому большинство команд теперь используют Testing-Library, поскольку она оценивает вывод компонентов. Она работает путем визуализации всего дерева компонентов в виртуальном браузере (JSDOM). И она предоставляет утилиты, которые имитируют реальное использование.
Adobe стремится сделать еще один шаг вперед, записывая сценарии использования компонентов в виде историй. Затем повторно использовать их в Jest для запуска тестов взаимодействия. Это возможно благодаря Component Story Format — переносимому формату, основанному на модулях JavaScript ES6. Таким образом, вы можете использовать одну и ту же историю во время разработки, а затем снова в визуальном, композиционном и интерактивном тестировании.
Оно того стоит?
Иногда. Тесты взаимодействия гарантируют, что связь между компонентами работает. Ситуации протекают, и состояние обновляется. На практике это означает, что вы получаете умеренный охват, написав тесты с относительно низкими эксплуатационными расходами.
Тестирование доступности — работает ли приложение для всех пользователей?
Ваши пользователи взаимодействуют с пользовательским интерфейсом различными способами. Например, с помощью мыши, сенсорного экрана, клавиатуры и устройства чтения с экрана. Доступность — это практика, позволяющая сделать веб-сайты удобными для всех людей.
Самый точный способ проверки доступности — это ручная проверка с помощью комбинации браузеров, устройств и программ чтения экрана. Компании часто нанимают внешних консультантов или обучают кого-то внутри компании. Но это может быть непрактично, поскольку ручное тестирование каждого изменения пользовательского интерфейса отнимает много времени. Поэтому команды используют гибридный подход, сочетающий ручное тестирование и автотесты.
В качестве первой линии QA используйте компьютерное тестирование для выявления очевидных нарушений доступности. Это работает путем аудита рендеринга DOM по набору эвристик (например, с помощью библиотеки Axe). После завершения автоматизированных проверок вручную проверьте пользовательский интерфейс, чтобы найти тонкие проблемы.
Сочетание автоматизированной и ручной работы в конечном итоге является прагматичным балансом охвата и усилий. Вы получаете быстрый цикл обратной связи, в котором можно найти и устранить проблемы доступности до того, как они попадут в производство. Большинство команд используют Axe для проведения автоматизированных проверок компонентов. Это также позволяет им проводить целевое тестирование для более быстрого обнаружения ошибок. Например:
- Атомарные компоненты: оцените осведомленность о клавиатуре, плохой цветовой контраст или отсутствие атрибутов ARIA (Сокращенно от Accessible Rich Internet Applications (Доступные многофункциональные интернет-приложения), ARIA — это подмножество атрибутов HTML (обычно с префиксом aria-), которые изменяют то, как вспомогательные программы, такие как программы чтения с экрана, распознают ваши страницы).
- Композиции: проверьте, не мешают ли компоненты друг другу работать.
- Страницы: убедитесь, что все заголовки и различные разделы отображаются в правильном порядке.
Команда Twilio Paste использует интеграцию jest-axe для проведения автоматизированного аудита доступности компонентов. Axe также доступен в виде плагина для Storybook.
Оно того стоит?
Всегда. Это не только полезно для ваших пользователей, но и является требованием закона. Axe — это инструмент, который не требует больших вложений. Его использование не сделает ваше приложение автоматически доступным, но позволит выявить множество проблем на ранней стадии.
Тестирование пользовательского потока — работает ли ваше приложение от начала до конца?
Даже самая простая задача требует от пользователя выполнения последовательности шагов, охватывающих множество компонентов. Это еще одна потенциальная точка отказа. Такие инструменты, как Cypress и Playwright, позволяют проводить сквозное тестирование (E2E) всего приложения для проверки таких взаимодействий.
Тестирование всего приложения требует значительной работы с инфраструктурой. Вы должны создать тестовую среду, в которой будут развернуты все части вашей системы в тандеме — фронт-энд, бэк-энд и другие сервисы. Собрать тестовые данные. А затем подключиться к облачному браузеру, чтобы запустить тесты.
Учитывая эти нюансы, большинство команд предпочитают отказаться от комплексных E2E-тестов для своих пользовательских интерфейсов, отдавая предпочтение тестированию взаимодействия и композиции. Или же они ограничиваются небольшим набором E2E-тестов, чтобы убедиться, что приложение продолжает работать после деплоя (процесс выкладки новой версии сайта на сервер (или сервера), другими словами — запуска) в продакшн.
Однако для некоторых команд этот компромисс стоит того. Например, компания O'Reilly использует Docker для деплоя всей своей инфраструктуры. А затем запускает E2E-тесты с помощью Cypress, чтобы проверить пути пользователей.
Оно того стоит?
В исключительных случаях. Тесты E2E требуют значительного компромисса. Они обеспечивают высокий уровень уверенности, но требуют времени и усилий для запуска и тестирования всей системы. Поэтому ограничьте E2E-тесты только критическими потоками пользователей, например, регистрация → добавление в корзину → покупка.
Автоматизируйте скучные части
Если вы такой же разработчик, как и я, создание пользовательского интерфейса доставляет больше удовольствия, чем тестирование каждого состояния. Так как же тестировать каждую функцию и при этом успевать писать код?
Все команды, с которыми я беседовал, используют сервер непрерывной интеграции ( Continuous Integration — CI), чтобы сократить ручные усилия. Каждый раз, когда вы вводите код, CI автоматически запускает набор тестов. Тесты выполняются в фоновом режиме, а результаты сообщаются в запросе на выгрузку для всех желающих.
Автотестирование CI обнаруживает ошибки пользовательского интерфейса автоматически, что дает уверенность в том, что пользовательский интерфейс работает корректно до деплоя в продакшн.
Ваша стратегия тестирования пользовательского интерфейса
Тестирование пользовательского интерфейса является неотъемлемой частью создания высококачественного опыта. Выработать прагматичную стратегию тестирования может быть непросто, поскольку площадь поверхности приложения очень велика, и существует множество способов ее протестировать.
В итоге приходится искать компромиссные решения. Некоторые тесты просты в использовании, но дают ложную уверенность. Другие оценивают систему в целом, но работают медленно.
Опросив десять команд, чтобы выяснить, какие методы тестирования пользовательского интерфейса действительно работают, я составил короткий список инструментов, которые они рекомендуют.
- 📚 Storybook для изоляции компонентов от их контекста для упрощения тестирования.
- ✅ Chromatic для выявления визуальных ошибок в атомарных компонентах и проверки композиции/интеграции компонентов.
- 🐙 Testing Library для проверки взаимодействий и базовой логики.
- ♿️ Axe для аудита доступности.
- 🔄 Cypress для проверки пользовательских потоков в нескольких компонентах.
- 🚥 GitHub Actions для непрерывной интеграции
В таблице ниже приведены плюсы и минусы каждого метода тестирования пользовательского интерфейса, а также частота его использования.
Пока что в этой статье мы лишь поверхностно рассмотрели тестирование пользовательского интерфейса. В следующих статьях я углублюсь в каждый слой различных видов тестирования и разберусь с тем, как реализовать стратегию тестирования пользовательского интерфейса. Присоединяйтесь к списку рассылки, чтобы получать уведомления о выходе новых статей по тестированию.