Три вида сбоев во время выполнения, которые должно покрывать тестирование веб-приложений

Остаточное состояние

  • Модальное окно закрывается и оставляет заблокированной прокрутку. Фильтр сохраняется там, где в этом нет никакого смысла.

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

Отрисовка раньше данных

  • Страница отрисовалась, запрос завершился, повторной отрисовки не произошло.

  • Обычно воспроизводится нестабильно — поэтому и проходит через ревью.

Второй пользователь

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

  • Прекрасно работает у всех, кто это делал.

Проверка, которая ловит большую часть такого

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

Что проверять

  • То, что подтвердится после перезагрузки. Сообщение об успехе — не доказательство того, что что-то сохранилось. Запросите данные обратно.

  • Отсутствие того, чего быть не должно. После удаления строки нет. После выхода из аккаунта данные не видны.

  • Поведение для кого-то другого. Второй аккаунт не видит записи первого.

Где здесь локальная разработка

Работа над веб-приложением идёт на localhost задолго до любого деплоя, и проверка, которая работает только с публичным URL, приходит слишком поздно, чтобы повлиять на то, что вы делаете. Для прогонов фронтенда CLI умеет пробрасывать туннель к приложению, запущенному на вашей машине, — так что проверка доступна прямо во время работы. Подробности — в репозитории CLI.

Терминал

npm install -g @testsprite/testsprite-cli
testsprite setup

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

Тест с двумя вкладками

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

Сделайте что-нибудь в первой, затем посмотрите на вторую. Большинство веб-приложений ведут себя здесь плохо в том или ином смысле, и характер этого «плохо» многое говорит. Список, который не обновился, — обычно нормально. Устаревшее действие, которое успешно проходит и перезаписывает более свежие данные, — настоящий баг. Сессия, которая разлогинивает одну вкладку, когда другая обновляет токен, — настоящий баг. Оптимистичное обновление, которое так и не приходит в согласованное состояние, — настоящий баг.

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

Запускайте проверки непрерывно

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

  • GitHub App — это вебхук, который вы настраиваете в дашборде TestSprite. Он слушает событие деплоя, которое ваш пайплайн и так генерирует, поэтому в репозитории ничего не меняется.

  • GitHub Actions встраивает этот шаг прямо в ваш workflow и настраивается из терминала.

Как TestSprite проверяет работающее приложение

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

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

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

Почему это не всплывает на код-ревью?

Потому что это свойства взаимодействия между состоянием сервера, состоянием браузера и историей. В диффе нет ничего из этого.

Можно ли покрыть это юнит-тестами?

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

Как надёжно проверить второго пользователя?

Держите в каждом окружении второй аккаунт и проходите один и тот же сценарий от обоих. Это самая дешёвая результативная проверка в тестировании веб-приложений.

А как быть с мобильными браузерами?

Различия во вьюпорте вскрывают отдельный набор проблем с вёрсткой и взаимодействием. Если у вас есть мобильный трафик, основные сценарии стоит покрыть и на мобильном размере экрана.

Что из этого можно запускать локально?

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

Коротко

Сделайте это дважды, от двух пользователей, с перезагрузкой.

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