Изучите наиболее распространенные плохие практики и способы реализации правильных решений.

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

Что касается долларов США, то, согласно прогнозам, область автоматизации тестирования вырастет с 12,6 млрд долларов в 2019 году до 28,8 млрд долларов к 2024 году. Это рост более чем на 100% в течение пяти лет. Такой астрономический рост откроет множество возможностей.

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

Ожидающий…

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

Пример правильного использования ожидания:

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

Пример неправильного использования ожидания:

Вместо того, чтобы писать приведенный выше код, используйте встроенные стратегии ожидания, такие как ожидание элементов или ответов. Учтите, что нажатие кнопки «newHeadingButton» в приведенном выше примере отправляет запрос. Мы можем дождаться завершения запроса, прежде чем предпринимать следующие действия.

Слишком буквальное отношение к тестированию пользовательского интерфейса

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

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

  1. Регистрация нового пользователя
  2. Вход в приложение

Вместо этого создайте запрос для нового пользователя с помощью API вашего приложения, а затем попытайтесь войти в систему с новыми учетными данными. Это можно легко сделать, используя встроенную библиотеку запросов и псевдонимы Cypress.

Аналогичный шаблон может быть использован для Playwright с использованием библиотеки JavaScript HTTP, такой как Requestify.

Тестирование независимо от CI

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

Инженеры по тестированию должны работать с инженерами по надежности сайта или по инфраструктуре, чтобы гарантировать, что автоматические тесты выполняются для каждой сборки или каждого слияния. Тесты можно даже запускать с фиксацией или предварительным запуском при использовании таких пакетов, как Pre-Commit, если группа инженеров решит принять такой инструмент.

Я лично рекомендую использовать Pre-Commit в команде и запускать линтинг / форматирование на pre-commit, а затем модульные тесты на pre-push. Поскольку тесты пользовательского интерфейса занимают больше времени, я бы запускал их для каждой сборки или для каждого слияния, используя что-то вроде Github Actions или рабочего процесса Jenkins.

Поведенческие накладные расходы

Раньше я был большим сторонником разработки, основанной на поведении (BDD), настолько, что написал стандарт передовых практик для двух компаний, в которых я работал в прошлом. Однако я отказался от использования BDD после того, как пришел к выводу, что этот процесс практически не дает никакой ценности, действуя как источник боли при рефакторинге.

Инструменты разработки, основанные на поведении, такие как Cucumber, прекрасно подходят для работы в мечтательном сценарии, когда вся компания увлеклась искусством BDD. Однако слишком часто команда тестирования пишет на Gherkin, в то время как другие аспекты бизнеса либо игнорируют эту практику, либо не вносят свой вклад. В этом случае BDD теряет свою ценность как инструмент сотрудничества между отделами. Вместо того чтобы сблизить управление продуктом, разработку и обеспечение качества, эта практика приводит к отчуждению QA.

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

// login.feature
Feature: Application Login
    As a user,
    I would like to login to the application
    Scenario: Login with valid information
        Given we visit the login page
        When we submit valid credentials
        Then we should redirect to our profile page

Теперь нам нужен файл шагов.

Что, если рабочий процесс входа больше не перенаправляет на страницу профиля?

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

Вместо использования BDD вам следует писать более декларативные пользовательские поездки.

Приведенные выше пути достаточно декларативны для читателя (будь то тестировщик, менеджер по продукту или разработчик), что тест принимает пользователя, вводит действительные данные и успешно отправляет их. Никаких шагов, функций или сложных накладных расходов не требуется, только простой JavaScript.

Условия

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

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

  • Если пользователь вошел в систему, выйдите из системы, затем войдите в систему
  • Если пользователь не авторизовался, авторизуйтесь

Из-за этой условной логики тесты были крайне ненадежными. Иногда они проходили, хотя в большинстве случаев полностью терпели неудачу. Я решил удалить условную логику в пользу метода выхода из системы API на этапе демонтажа. Пользователю всегда приходилось входить в систему (если выполнение теста не было прервано вручную), что делало тесты намного более надежными при запуске.

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

Давайте рассмотрим пример приложения, которое находится в разгаре кампании A / B-тестирования. Приложение представляет собой книжный магазин, который отображает определенную книгу для группы A и другую книгу для группы B. Вместо условной логики мы могли бы реализовать макет ответа, чтобы всегда показывать книгу для группы A.

Теперь наш тест детерминирован и надежен, поскольку мы создали состояние теста с помощью API, а не пытались сделать это через пользовательский интерфейс.

Выбор неправильных селекторов

Часто использование правильных критериев выбора может быть сложной задачей. Распространенным анти-шаблоном в автоматизации тестирования является использование очень хрупких селекторов при построении объектов страницы или написании тестов. Хрупкие селекторы - это те, которые могут измениться из-за рефакторинга реализации. Неправильным критерием выбора будет использование неуникальных идентификаторов и классов или Xpath.³

Cypress специально облегчает эту боль, применяя методы JQuery .first() и .last(), а также методы обхода DOM, такие как .sibling() и .parent().

// Cypress
cy.get('.chat-message').last();

Рекомендуется усилить методы выбора путем добавления настраиваемых селекторов, а не полагаться на эти методы выбора (если у вас нет доступа к исходному коду).

В большинстве случаев инженеры-тестировщики должны синхронизироваться со своей командой разработчиков, чтобы гарантировать добавление уникальных селекторов в кодовую базу. К ним относятся такие селекторы, как data-id, data-test-id, data-cy или любые их варианты. Их можно использовать как любой атрибут в среде автоматизации.

Резюме

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

Ресурсы

  1. Рынок автоматизации тестирования. Фирма маркетинговых исследований, www.marketsandmarkets.com/Market-Reports/automation-testing-market-113583451.html.
  2. Условное тестирование. Документация Cypress, 15 февраля 2021 г., docs.cypress.io/guides/core-concepts/conditional-testing.html#Definition.
  3. "Лучшие практики." Документация Cypress, 15 февраля 2021 г., docs.cypress.io/guides/references/best-practices.html#Selecting-Elements.

Джонатан Томпсон - старший инженер по качеству, специализирующийся на автоматизации тестирования. В настоящее время он проживает в Роли, Северная Каролина, со своей женой и голдендудлом по имени Уинстон. Вы можете связаться с ним в LinkedIn или подписаться на него в Twitter или Github.