Изображение от https://unsplash.com/@kellysikkema
Изображение от https://unsplash.com/@kellysikkema

В этой статье вы узнаете:

  • Что такое Cypress и когда его стоит использовать

  • Основы тестирования с использованием Cypress

  • Расширенные команды Cypress

  • Взаимодействие с элементами пользовательского интерфейса

  • Лучшие практики с использованием Cypress


Введение

Чтобы протестировать свои приложения, вам потребуется сделать следующие шаги:

  • Запустить приложение

  • Подождать пока сервер запустится

  • Провести ручное тестирование приложения(нажать на кнопки, ввести случайные текст в поля ввода или отправить форму)

  • Проверить, что результат вашего теста корректен(изменения заголовка, части текста и т.д.)

  • Повторить эти шаги ещё раз после простых изменений кода

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

Именно здесь в игру вступает Cypress. При использовании Cypress единственное, что вам нужно сделать, это:

  • Написать код вашего теста(нажатие на кнопку, ввод текста в поля ввода и т.п.)

  • Запустить сервер

  • Запустить или перезапустить тест

Только и всего! Библиотека Cypress выполняет все тесты за вас. И самое приятное, что она не только сообщает вам все ли ваши тесты успешны или нет, но также сообщает вам, какой тест не удался.

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

Теперь, когда мы обсудили преимущества Cypress, давайте узнаем об основах этой библиотеки.


Начало

Установка и настройка Cypress

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

Инициализация проекта
Инициализация проекта

Наконец, чтобы установить библиотеку Cypress:

Установка Cypress
Установка Cypress

Примечание . Если вы используете дистрибутив Linux, перейдите к этим инструкциям, прежде чем продолжить установку Cypress через NPM.

Теперь, когда Cypress установлен, попробуйте запустить его с помощью следующей команды:

Открытие Cypress
Открытие Cypress

Она открывает запускалку тестов(Test Runner):

Интерфейс Test Runner
Интерфейс Test Runner

А теперь давайте перейдём к написанию тестов.


Основы Cypress

Создание файла

Cypress требует, чтобы все наши тесты находились в каталоге cypress/integration. Сначала перейдите в этот каталог:

Переход к cypress/integration
Переход к cypress/integration

Теперь создайте файл JavaScript с именем basicTest.js:

Создание JavaScript файла
Создание JavaScript файла

Если вы не отключили сервер Cypress, ваши новые файлы появятся в Test Runner в реальном времени:

Обновление структуры файлов в реальном времени
Обновление структуры файлов в реальном времени

Теперь давайте напишем наш первый тест.

Простые тесты с утверждением и ожиданием значения

В вашем файле /cypress/integration/basicTest.js напишите следующий код:

Код к файлу basicTest.js
Код к файлу basicTest.js
  • Строка 1: Функция describe сообщает Cypress название набора наших тестов.

  • Строка 2: Функция it, обозначает название теста.

  • Строка 3: Создаём утверждение. Здесь мы подтверждаем, что 2 + 2 равно 4. Если тест вернёт false, то он будет немедленно остановлен.

Чтобы запустить вашу программу, щёлкните по basicTest.js в вашем сервере Cypress.

Щелчок по basicTest.js в Test Runner
Щелчок по basicTest.js в Test Runner

Результат запуска:

Результат запуска теста
Результат запуска теста

Отлично! Значит, наше утверждение было успешным.

Что, если мы сделаем заведомо ложное утверждение? Теперь в /cypress/integration/basicTest.js добавьте следующий код в пределах функции describe:

Код для добавление в basicTest.js
Код для добавление в basicTest.js
  • Строка 2: Если сумма 4 и 5 равна 10, тест будет пройден. В противном случае, незамедлительно остановлен.

Снова запустите код. Результат будет:

Результат нашего второго теста
Результат нашего второго теста

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

Давайте больше поиграем с утверждениями. Добавьте в basicTest.js следующий код:

Код для добавления в basicTest.js
Код для добавления в basicTest.js
  • Строка 2: Если сумма 5 и 5 не равна 100, то тест должен пройти.

Результат выполнения теста:

Результат теста: успешно!
Результат теста: успешно!

Отлично! Наш тест прошел. Функция expect выполняет  BDD (behavior-driven) утверждения. В следующем разделе мы выполним утверждения, основанные на тестировании(test-driven assertions).

Сейчас /cypress/integration/basicTest.jsдолжен выглядеть так:

Написание утверждений основанных на тестировании(test-driven assertions) с явным использованием assert

Мы даже можем писать утверждения на основе TDD с использованием assert.

В вашем файле basicTest.js напишите следующий код:

  • Строка 2: Создаём объект со свойствами name и age.

  • Строка 6: Функция isObjectподтверждает, что переменнаяpersonявляется объектом. Если результат true, то будет напечатано value is object. В противном случае будет показано, что этот тест не прошел.

  • Строка 10: Убеждаемся, что переменная nameсодержит строковое значение.

  • Строка 14: Убеждаемся, что переменная name не является целым числом.

Запустите код. Результатом будет:

Результат запуска нашего теста
Результат запуска нашего теста

Отлично! Наш код работает. В следующем разделе мы научимся работать с сайтами через Cypress.

Сейчас наш basicTest.jsдолжен выглядеть так:

Запуск веб-сайтов

Здесь мы попробуем запустить Demoblaze , сайт, созданный для проведения тестов.

В своей папке /cypress/integration/ создайте файл с именем basicCommandsTest.js. В этом файле напишите следующий код:

Код для basicCommandsTest.js
Код для basicCommandsTest.js
  • Строка 3: Используем метод visit, чтобы сообщить Cypress о переходе на веб-сайт Demoblaze.

Сохраните свой код и нажмите на basicCommandsTest.js в меню Test Runner:

Клик по basicCommandsTest.js вTest Runner
Клик по basicCommandsTest.js вTest Runner

Результат запуска:

Отлично! Наш код работает. В следующем разделе мы более глубоко погрузимся в тестирование с помощью Cypress.

В итоге basicCommandsTest.jsдолжен выглядеть так:


Cypress: Расширенные команды

В этом разделе мы попытаемся взаимодействовать с элементами на странице. Однако, прежде чем продолжить этот процесс, нам нужно сначала научиться идентифицировать элементы HTML в Cypress.

Как идентифицировать элементы

Cypress использует селекторы JQuery для идентификации компонентов на веб-странице.

Например, чтобы получить элемент myButton используя id, мы должны написать следующий код:

Получение элемента через id элемента
Получение элемента через id элемента

В качестве альтернативы, чтобы идентифицировать элемент myButton используя имя класса, могли бы использовать следующую строку:

Получение элемента через имя класса
Получение элемента через имя класса

Давайте теперь поработаем с взаимодействием с пользовательским интерфейсом нашего сайта.

Нажатие кнопки

В этом разделе мы будем использовать страницу The-Internet для запуска наших тестов. На этом веб-сайте мы будем использовать раздел добавления/удаления элементов.

Давайте сначала попробуем идентифицировать нашу кнопку «Добавить элемент».

Страница для тестирования
Страница для тестирования

Используя DevTools, заметьте, что у buttonесть свойство onclick, имеющее значение addElement().

Скриншот из DeveloperTools
Скриншот из DeveloperTools

Соответствующий селектор для этой кнопки будет выглядеть так:

Идентификация элемента
Идентификация элемента

В папке /cypress/integration создайте файл с именем runningClickCommand.js. В этом файле напишите следующий код:

  • Строка 2: Переходим на веб-страницу.

  • Строка 6: Связываем в одну цепочку получение элемента button и нажатие на эту кнопку.

Запустите код. Результат:

Вывод результата
Вывод результата

Отлично, наш код работает! Обратите внимание, что как только страница загрузилась, в нашем тесте автоматически происходит нажатие на кнопку Add Element.

Давайте теперь поработаем с вводом текста в текстовое поле.

Ввод текста

В этом разделе мы будем использовать страницу The-Internet’s login. Нам нужен способ сначала идентифицировать элементы.

Скриншот сайта для тестирования
Скриншот сайта для тестирования
Скриншот из DeveloperTools
Скриншот из DeveloperTools
Скриншот из DeveloperTools
Скриншот из DeveloperTools

Поле username имеет id равное username, а поле password имеет id равное password. Кроме того, кнопка Login имеет свойство type равное submit. Таким образом, для определения полей username и password, нам понадобится селектор JQuery id:

Идентификация элемента через его id
Идентификация элемента через его id

Более того, чтобы получить кнопку button, нам понадобится селектор атрибутов , например:

В своей папке /cypress/integration создайте файл с именем runningTypeCommand.js. В этом файле напишите следующий код:

  • Строка 3: Переходим на страницу входа в систему.

  • Строка 6: Переходим в поле username и добавляем метод type в цепочку вызовов, чтобы напечатать в этом текстовом поле значение tomsmith.

  • Строка 7: Переходим в поле password и вводим SuperSecretPassword.

  • Строка 10: Нажимаем на кнопку «Отправить».

Запустите код. Результатом будет:

Вывод результата запуска кода
Вывод результата запуска кода

И мы закончили! В следующем разделе мы узнаем о работе с чекбоксами.

Переключение чекбоксов

В этом разделе мы будем использовать раздел чекбоксов на странице The-Internet .

Давайте сначала посмотрим на DevTools:

Developer Tools
Developer Tools

Оба этих чекбокса имеют свойство type со значениемcheckbox. Кроме того, они также являются дочерними элементами для элементаform с id равным checkboxes. В этом случае мы бы использовали селектор JQuery родитель-потомок:

Идентификация наших чекбоксов
Идентификация наших чекбоксов

В каталоге /cypress/integration/ создайте файл с именем runningCheckCommand.js и напишите следующий код:

  • Строка 4: Находим обе группы чекбоксов, а затем используем метод check, чтобы отметить их выбранными.

  • Строка 7: Просим Cypress приостановить процесс тестирования на одну секунду.

  • Строка 8: Получаем список отмеченных чекбоксов. Затем используем метод uncheck, чтобы снять выбор.

Запустите код. Результат:

Результат запуска теста
Результат запуска теста

Отлично! Наш код работает. Давайте теперь поработаем над неявными утверждениями с помощью Cypress.

Неявные утверждения

Ранее мы выполняли утверждения для переменных и объектов. Однако в реальном мире мы хотели бы выполнять утверждения для текста, расположенного в нашем элементе HTML, или проверять, есть ли у нашего элемента ul дочерние элементы li или нет.

Для выполнения таких утверждений мы будем использовать ключевое слово should. В этом разделе мы будем делать неявные утверждения на странице добавления элемента — The-Internet’s Add Element

Скриншот тестируемой страницы
Скриншот тестируемой страницы
Developer Tools
Developer Tools

Наша кнопка Delete имеет класс added-manually. Мы хотим выполнить следующее утверждение для этого элемента button:

Наше утверждение
Наше утверждение

Для этого мы должны использовать следующий синтаксис:

Получение элемента и за тем утверждение
Получение элемента и за тем утверждение

Альтернативно, можем выполнить такое утверждение:

Наше утверждение
Наше утверждение

Мы можем использовать эту строку кода:

Получение элемента и затем утверждение
Получение элемента и затем утверждение

Перейдите в /cypress/integration/runningClickCommand.jsи добавьте следующий код:

Код для runningClickCommand.js
Код для runningClickCommand.js
  • Строка 1: Получаем элементы с классом added-manually. Затем проверяем, что их количество(have.length) равно единице.

  • Строка 3: Получаем кнопку Add Element, а затем проверяем, что текст на кнопке(have.text) действительно будет Add Element.

Запустите код. Результат в конце теста должен быть следующим:

Результат запуска
Результат запуска

Отлично! Наш код работает. Теперь перейдем к изучению команды each.

В итоге cypress/integration/runningClickCommand.js должен выглядеть так:

Команда each

Взгляните еще раз на The-Internet’s Add Elements page:

Скриншот тестового сайта
Скриншот тестового сайта

Чтобы удалить все эти элементы, мы можем вручную прокликать все кнопки Delete. Это возможно; однако рассмотрим ситуацию, когда кнопок Delete больше сотни. Следовательно, удаление всех их вручную займет много времени.

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

Откройте Developer Tools:

Все наши кнопки Delete имеют свойство class равное added-manually. В этом случае мы будем использовать селектор классов и соединять его с командой each, например:

Получение элемента и использование each затем
Получение элемента и использование each затем

Перейдите в /cypress/integration/runningClickCommand.jsи добавьте следующий фрагмент кода:

Код для runningClickCommand.js
Код для runningClickCommand.js
  • Строка 2: Получаем все элементы, у которых есть класс .added-manually. Каждый элемент в серии будет представлен параметром $el.

  • Строка 3: Обёртываем этот элемент, чтобы мы могли выполнять с ним команды Cypress. Здесь мы отправляем команду щёлкнуть по этим элементам.

Результат выполнения кода должен быть следующим:

Результат выполнения кода
Результат выполнения кода

Наш код работает! Поскольку наш тест был быстрым, давайте попробуем добавить на страницу больше элементов.

Найдите следующий фрагмент кода:

Измените это так:

  • Строка 2: Запускаем цикл, чтобы сообщить Cypress, что нужно нажать кнопку Add Element 20 раз.

Запустите код еще раз. Результат должен быть таким:

Результат выполнения кода
Результат выполнения кода

Как видите, наша программа автоматически удалила все элементы на странице без каких-либо ручных усилий. Отлично!

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

В итоге cypress/integration/runningClickCommand.jsдолжен выглядеть так:


Лучшие практики

Держите тесты изолированными

Рассмотрим ситуацию, когда вы тестируете свое приложение. Структура вашего проекта будет выглядеть примерно так:

Не самая лучшая структура
Не самая лучшая структура

В вашем Test Runner это будет выглядеть так:

Отображение тестовой структуры в Test Runner
Отображение тестовой структуры в Test Runner

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

Хорошая структура проекта
Хорошая структура проекта

Следовательно, это выглядело бы так:

По возможности используйте собственные команды

Взгляните на этот фрагмент кода:

Пример кода
Пример кода

Обратите внимание, что мы вынуждены многократно использовать команды getи type. Здесь мы можем реализовать собственные команды, чтобы сделать их короче.

В вашем cypress/support/commands.jsнапишите этот код:

  • Строка 1: Создаём собственную команду, которая будет иметь два параметра identifier и data.

  • Строка 2: Получаем элемент с соответствующим идентификатором, а затем вводим в него данные.

Примечание . Считается хорошей практикой записывать свои собственные команды в файл /cypress/support/commands.js.

Теперь вернитесь в свой тестовый файл и замените его вот так:

Пример кода
Пример кода

Как видите, наш код выглядит значительно короче.

Избегайте «атомарных» тестов

Взгляните на этот фрагмент кода:

Здесь мы повторно выполняем тесты на HTML элементе с id равным first.

Cypress не одобряет такого поведения. Это неэффективно, и есть способ лучше переписать этот код, например:

Мы можем использовать метод and для связывания дополнительных команд should с нашим элементом.

Не запускайте сервер в Cypress

Команда exec присутствует для запуска команд в терминале. Но запускать сервер с помощью этой команды крайне не рекомендуется.

Если вы хотите протестировать свое приложение на localhost, сначала запустите сервер, а затем запустите свой тест Cypress.

Команды терминала
Команды терминала

Репозиторий GitHub и дополнительные ресурсы

Код GitHub

Дальнейшее чтение


Заключение

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

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