Для начала простой вопрос: Зачем мы тестируем наш код? Самый простой ответ — получить как можно больше уверенности, чтобы а) наш код работал так, как ожидалось, и б) наши пользователи могут выполнять задачи, которые они ожидают.
Но между тестированием бэкенда и фронтенда существует гораздо большее несоответствие/серая зона. В то время как серверная часть обычно сводится к рабочим процессам ввода-вывода, пользовательский интерфейс, как правило,… ну, более изменчивый и сложный, учитывая нелинейный и часто перекрестный путь пользователя по мере роста системы.
Со временем во внешних интерфейсах появилось два основных типа тестов, помогающих бороться с этой растущей сложностью: интеграционные тесты (например, testing-library) и e2e-тесты ( например, драматург). У обоих есть свои плюсы и минусы, и они заслуживают своего места в стеке тестирования. 👌
Но тем не менее, у большинства команд разработчиков есть мучительный, оставшийся без ответа вопрос: ГДЕ МЫ ПРОВЕРЯЕМ ЭТИКЕТКИ ИНТЕРФЕЙСА? (И другие копии/тексты тоже?) Если они не ответят на этот вопрос правильно, это неизбежно приведет к множеству неаккуратных и/или избыточных тестов.
Важно разобраться в этом фундаментальном вопросе глубже (например, 5 Почему), прежде чем предлагать какое-либо реальное решение. Каждая команда должна спросить:
В: Почему мы хотим тестировать этикетки? Нам это нужно?
- Подумайте об этом крепко. Да, в теории здорово тестировать ВСЕ, но есть высокая стоимость, связанная с тестированием, как внедрением, так и поддержкой. Подумайте о своей машине — не будет ли безопаснее каждый день возить ее к механику для проверки? Ну да, но никто не делает, потому что слишком высока стоимость, как времени, так и денег. Даже просто ежедневный осмотр был бы полезен, но большинство из нас никогда этого не делает. Если есть случайный вмятин или царапина, то так тому и быть! Когда мы поймаем это случайно, тогда мы с этим и разберемся.
- Некоторые тексты важнее тестировать, чем другие. Может помочь расстановка приоритетов в списке.
В: Какова взаимосвязь работы между изменением метки и обновлением теста для нее?
- Если это всегда один к одному, то действительно ли это полезно, или это просто временная синхронизация занятой работы?
В: Как часто меняются ярлыки? (Насколько гибкими/изменяемыми должны быть метки?)
- Предположим, что обычно ответ на этот вопрос — «в любое время» или «часто». Дело в том, что менеджер по продукту должен иметь возможность проводить маркетинговые исследования и возвращаться к команде разработчиков с ЛЮБЫМИ косметическими изменениями в продукте, включая любой текст. В любое время.
В: Насколько мы готовы рискнуть сломать тест (т. е. остановить развертывание!) при изменении метки?
- Это критическая стоимость для взвешивания! Серьезно. Многие тестовые наборы разваливаются, когда начинают давать сбои, но никто в команде не заботится об исправлении «несущественных» неработающих тестов, поскольку в конце концов они работают над новыми важными функциями. верно?! Перенесемся на пару недель вперед, и ложноположительный шум станет сложнее обнаружить, поэтому доверие к системе тестирования начнет снижаться; а качество отходит на второй план, поскольку развертывание становится грустным ритуалом суеверий и действий «больных», чтобы избежать устранения неполадок в плохом развертывании. (Да, я видел это много раз.) Не позволяйте лейблам делать это с вашим проектом.
Хорошо, я думаю, что суть ясна. Во-первых, тщательно подумайте о тестировании меток/текста!
Теперь предположим, что вы составили приоритетный список критически важных меток в системе — например, кнопки CTA, заголовки страниц и кнопки навигации. Большой! Теперь… должны ли мы тестировать их в E2E (т. е. на уровне браузера) или в интеграции (т. е. на уровне веб-компонента)?
Чтобы ответить на этот вопрос, давайте рассмотрим еще один важный вопрос: являются ли ярлыки на самом деле: А)системной конфигурацией или Б) бизнес-логикой? Вот несколько ключевых моментов, которые следует тщательно обдумать:
- Большинство крупных систем используют i18n, что означает, что метки больше не определяются в строке, а предоставляются через вызов функции, чтобы вернуть правильную строку языка. Например, в React мы могли бы сделать что-то вроде этого кода:
<Button label={i18n("Submit")} />
- Должны ли мы выбирать компоненты для тестирования по их ярлыку, который наши пользователи действительно увидят, или более стабильному
test-id
?
По моему опыту, эта структура сработала лучше всего (все рассмотрено):
- МЕТКИ ЯВЛЯЮТСЯ КОНФИГУРАЦИЕЙ (поскольку они не являются логическими и не жестко запрограммированы; вместо этого они предоставляются через данные конфигурации и будут меняться в зависимости от системы пользователя, в которой они запущены).
- Таким образом, приоритетные/критические метки следует тестировать в E2E (а не в интеграции); именно здесь мы тестируем путь пользователя/опыт, и где браузер можно настроить для работы на нескольких языках. База проекта тестового набора должна быть разработана с использованием простых соглашений, чтобы максимизировать DRY-код/минимизировать настройку для собственных «пользовательских» меток каждого языка.
- Интеграционные тесты должны по большей части игнорировать метки/текст. (Если вы хотите... вы можете подсчитать с помощью шпиона, сколько раз вызывается ваша функция
i18n
. Но это, скорее всего, деталь реализации, которую в любом случае даже не стоит проверять!) - Как E2E, так и интеграционные тесты должны выбирать отображаемые веб-компоненты только через стабильный
test-id
, чтобы свести к минимуму количество поломок набора тестов, в противном случае выбирая нестабильный текст метки (т.е.select('[test-id=buy-now]')
, а неselect({text: 'Buy Now!'})
).
Как вы думаете, вы согласны? Надеюсь, это поможет вашей команде лучше понять плюсы и минусы. Дай мне знать в комментариях.
Вы можете следить за мной в Twitter и YouTube. Давайте продолжим интересные разговоры о разработке Sr JS вместе!