Для начала простой вопрос: Зачем мы тестируем наш код? Самый простой ответ — получить как можно больше уверенности, чтобы а) наш код работал так, как ожидалось, и б) наши пользователи могут выполнять задачи, которые они ожидают.

Но между тестированием бэкенда и фронтенда существует гораздо большее несоответствие/серая зона. В то время как серверная часть обычно сводится к рабочим процессам ввода-вывода, пользовательский интерфейс, как правило,… ну, более изменчивый и сложный, учитывая нелинейный и часто перекрестный путь пользователя по мере роста системы.

Со временем во внешних интерфейсах появилось два основных типа тестов, помогающих бороться с этой растущей сложностью: интеграционные тесты (например, 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 вместе!