Playwright + Cucumber необычная связка. Практические примеры написания авто тестов

в 21:15, , рубрики: cucumber, playwright, TypeScript, автоматизация, тестирование
Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 1

1. Введение

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

Я решил использовать связку из этих двух инструментов исходя из того что BDD тесты – это простой текст, на человеческом языке, написанный в форме истории (сценария), описывающей некоторое поведение, значит Cucumber прост для понимания как начинающему специалисту с небольшим опытом тестирования так и для лица технически не подкованным. При этом мощная сердцевина playwright дает большие возможности для написания авто тестов. Градация фреймворка на части позволит опытному специалисту создавать базовую часть функций (в данном примере на Playwright + TypeScript), а начинающему специалисту покрывать тестами приложение с использованием готовой базы и знаниями (Cucumber, X-path). PS возможно это станет более понятным в конце статьи.

Используемые фреймворки/инструменты:

  • Playwright

  • Cucumber

  • Typescript

  • NodeJS

2. Подготовительные работы

Для практики нам понадобиться простенькое web приложение / сайт. На пример это будет тестирование UI части некой signup/registration формы.
Оптимальный вариант запуск данного web приложения локально.
Вы можете как самостоятельно создать похожую страницу так и воспользоваться примером созданным мною. Желательно Чтобы сильно не загружать статью файлами, необходимый комплект файлов добавлен в git репозиторий -https://github.com/QaitkenQ/test_signup_form/tree/start_files

Шаги установки/настройки web приложения

  1. Установите Node JS.

  2. Создайте папку/каталог, например test_server.

  3. Распакуйте скачанные файлы в созданный каталог или загрузите файлы через консоль посредством git.
    Корневой каталог с web приложением будет выглядеть так: (*readme.md файл не обязателен)

    Web приложение

    Web приложение
  4. Откройте командную строку и перейдите в рабочий каталог или откройте каталог редактором кода (например VSC).

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

    • npm init ‑y

    • npm install express body-parser

  6. Запустите сервер командой

    • node server.js

  7. Убедитесь в работоспособности сервера открыв страницу http://localhost:3000 в браузере.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 3

Сайт готов для выполнения тестирования.

3. Установка/настройка Playwright и Cucumber

  1. Создайте корневой каталог для фреймворка со следующей структурой (например Cucuwright):

    Структура фреймворка

    Структура фреймворка

    Папка feature - содержит файл сценариев Cucumber.
    Папка src - содержит 3 папки с файлами:
    1. step_defenitions - здесь находятся файлы c детальным описанием шагов cucumber.
    2. page_objects - здесь находятся файлы с описанием элементов страницы и действия выполняемые с ними.
    3. utils - здесь находится файл BaseFunctions содержащий базовые операции/действия, которые могут быть применимы для любой страницы.
    Файл cucumber.js - содержит некоторые настройки для фреймворка Cucumber.
    Файл tsconfig.json - содержит настройки TypeScript.

    Стартовый комплект файлов так же доступен в репозитории на другой ветке https://github.com/QaitkenQ/test_signup_form/tree/cucuwright
    В них уже имеются предварительно созданные данные для начала тестирования страницы с singup form, которая уже запущена на http://localhost:3000 (Например файл шагов уже содержит хуки BeforeAll и AfterAll для корректного открытия и закрытия страницы браузера, необходимые зависимости между файлами уже описаны).

  2. Откройте командную строку и перейдите в рабочий каталог или откройте каталог редактором кода (например VSC).

  3. Установите фреймворк Playwright выполнив команду npm init playwright@latest и выбрав необходимые опции (язык typescript, каталог для тестов и т.п.)

  4. Установите фреймворк Cucumber выполнив команду npm i @cucumber/cucumber .

  5. Установите дополнительные библиотеки при необходимости
    npm install typescript
    npm install ts-node

  6. Созданные каталоги tests и tests-examples можно удалить.

  7. Проверьте работоспособность запустив команду npx cucumber-js

В консоль должно вывести сообщение о том что для текущего сценария шаги не определены. Файл singup_page.feature имеет один сценарий с 2 шагами. Значит все инструменты корректно установлены и зависимости работают.

Результат в консоли после выполнения всех подготовительных операций

Результат в консоли после выполнения всех подготовительных операций
  1. По желанию можно установить несколько расширений Cucumber для VSC.
    Cucumber (Gherkin)
    Cucumber Reference Support

4. Написание авто теста

Открываем файл сценариев signup_page.feature По умолчанию в нем уже присутствует 1 сценарий с 2 шагами. При создании нового файла .feature создайте аналогичный сценарий.

singup_page.feature

singup_page.feature

Сценарий 1

Шаг 1 - открытие страницы

Откроем файл signup_page_steps.ts и создадим основное описание для первого шага Given SignupPage open page

singup_page_steps.ts

singup_page_steps.ts

Откроем файл signup_page.ts, добавим url нашей страницы и создадим функцию openPage() для выполнения операции открытия страницы.

singup_page.ts

singup_page.ts

Все стандартные операции действия которые возможно выполнять с различными элементами вынесены в отдельный файл BaseFunctions.ts в папке utils.
Функция openPage() включает в себя базовую функцию openUrl() и передает параметр url.

Откроем файл BaseFunctions.ts и создадим базовую функцию openUrl(), финальным действием является метод goto().

BaseFunctions.ts

BaseFunctions.ts

Для выполнения данной операции можно было описать все в одной функции openPage(), но мы соблюдаем структуру разделения на операции которые относятся только для данной страницы и операциям которые могу быть применимы к любой другой.

Проверим на работоспособность шаг 1 - запускаем тест npx cucumber-js

Результат в консоли - Шаг 1 выполнен успешно.

Результат в консоли - Шаг 1 выполнен успешно.

Шаг 2 - проверка заголовка

Заголовок Sign Up page

Заголовок Sign Up page

Перейдем в файл signup_page_steps.ts и создадим описание для второго шага

When SignupPage verify the header "Sign Up page"

Добавление шага 2 signup_page_steps.ts

Добавление шага 2 signup_page_steps.ts

В данном случаи мы передаем значение(название заголовка) как строку {string}. При любых изменениях текста потребуется только изменить значение в .feature файле.

В файле signup_page.ts, добавим локатор (X-path, или атрибут элемента) для заголовка и создадим функцию isHeadingVisible() для выполнения операции поиска элемента.

Добавление шага 2 singup_page.ts

Добавление шага 2 singup_page.ts

В базовую функцию findElement() мы передаем значение селектора уже с замененным текстом из первоначального шага When SignupPage verify the header "Sign Up page". Посредством .replace значение %s становится равным Sign Up page.

Добавление функции findElement() в файл BaseFunctions.ts

BaseFunctions.ts

BaseFunctions.ts

Для данной операции был выбран метод waitForSelector().

Запускаем наш тест еще раз npx cucumber-js

Результат в консоли - Сценарий 1, 2 шага выполнено успешно

Результат в консоли - Сценарий 1, 2 шага выполнено успешно

Проверим точно ли мы тест выполняется, действительно ли нужная страница загрузилась и тест проверяет название заголовка - изменим значение в шаге 1 "Sign Up page" -> "Sign Up page Fail"

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 16

Получаем в консоли ошибку при выполнении шага 2 - Error: function timed out...

Результат - ошибка на шаге 2.

Результат - ошибка на шаге 2.

Похоже на правду, но хотелось бы получить больше информации в данном случае.

Перепишем функцию findElement() в файле BaseFunctions.ts. Добавим дополнительную функцию erifyElementExists(), которая будет выводить в консоль более детализированное описание об ошибке. Так же можно добавить значение таймаута.

BaseFunction.ts

BaseFunction.ts

Перезапускаем тест npx cucumber-js

Получаем в консоли другой результат - Error: Can't find the element '//h2[text()='Sign Up page Fail']' within the specified timeout

Результат в консоли - ошибка с подробностями

Результат в консоли - ошибка с подробностями

Теперь можно сразу проверить верный ли locator для элемента. Легко проверить скопировав этот путь из лога и вставив его в devtools.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 20

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

справляем значение - возвращаем изначальное в шаге 1.
Перезапускаем тест - 1 scenario (1 passed), 2 steps (2 passed). Получаем желаемый результат.

Сценарий 2 - Проверка ярлыков(labels)

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 21

Шаг 1 остается прежним открытие страницы.

Шаг 2 - проверка названия поля элемента

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

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 22

В файле singup_page_steps.ts описываем шаг 2 с учетом передачи значений из таблицы.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 23

В файле singup_page.ts создаем функцию verifyLabels() и добавляем селектор для элемента label.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 24

Данная функция использует уже имеющуюся базовую функцию findElement() из BaseFunctions.ts.

Так как у нас теперь 2 сценария, то запускаем только второй сценарий по тегу @test2 npx cucumber-js --tags=@test2

Результат тест пройден.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 25

Добавим в таблицу остальные ярлыки которые есть в форме

singup_page.feature

singup_page.feature

Перезапускаем сценарий 2 npx cucumber-js --tags=@test2

Результат - мы получили ошибку. Последний ярлык из таблицы "Accept learning the Cucuwright" - не может быть найден.

Результат в консоли - ошибка поиска элемента.

Результат в консоли - ошибка поиска элемента.

Выполнив небольшой анализ видно что ярлык для элемента checkbox имеет другую структуру в DOM дереве. Значит придется создать отдельный шаг для данного элемента.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 28

Создаем новый шаг в файле .feature. Создадим шаг с передачей табличных значений на случай использование данного метода для страницы с несколькими элементами checkbox.

singup_page.feature

singup_page.feature

В файле singup_page_steps.ts добавим описание шага

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 30

В файле singup_page.ts создаем функцию verifyCheckbox() и добавляем селектор для элемента checkbox_label. В селекторе мы использовали X-path для более детального уточнения элемента - элемент должен иметь тип checkbox с необходимым текстом.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 31

Запускаем тест npx cucumber-js --tags=@test2
Результат - сценарий выполнен успешно.

Результат Сценарий 2.

Результат Сценарий 2.

Для перепроверки можно выполнить быстрый дебаг добавив ошибку в значение(название) ярлыка - Accept learning the Cucuwright -> Accept learning th Cucuwright
В результате мы получим ошибку что элемент checkbox с данным текстом не может быть найден.

Результат - ошибка выполнения последнего шага.

Результат - ошибка выполнения последнего шага.

Сценарий 3 - Проверка введенных значений в поле ввода

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 34

Новый сценарий и шаг в файле .feature

singup_page.feature

singup_page.feature

В файле singup_page_steps.ts добавим описание шага.

singup_page_steps.ts

singup_page_steps.ts

В файле singup_page.ts добавим локатор для поля First Name и создадим функцию enterUserName(). Данная функция будет передавать данные в виде string базовой функции enterText().

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 37

Создадим базовую функцию enterText() в файле BaseFunctions.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 38

Проверим работоспособность теста npx cucumber-js --tags=@test3

Результат - тест выполнен успешно

Результат - тест выполнен успешно

Добавим следующий шаг к сценарию №3, проверка значения в поле ввода.
Новый шаг в фалйе .feature

singup_page.feature

singup_page.feature

В файле singup_page_steps.ts добавим описание шага.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 41

Для примера сделаем этот шаг универсальным и применимым к другим полям ввода. К дополнению к основной функции verifyFieldValue() создадим дополнительную функцию determineField() определяющую поле ввода. Так же необходимо добавить локаторы для остальных полей из формы в singup_page.ts файле.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 42

В зависимости от значения в шаге .feature файла будет определено поля для проверки и в случаи отсутствия его в списке для проверки будет выведена ошибка.

Далее в в файле BaseFunctions необходимо создать функцию verifyValue().

BaseFunctions.ts

BaseFunctions.ts

Запускаем тест еще раз npx cucumber-js --tags=@test3
Результат - тест выполнен успешно.

Результат

Результат

Небольшой дебаг - попробуем ввести ошибочное название поля First Name -> Fail Name

singup_page.feature

singup_page.feature

В результате мы получим ошибку с описанием, которое добавили немного ранее.
Unknown field 'Fail Name', please check the name

Результат

Результат

Сценарий 4 - проверка radio button элемента

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 47

Новый сценарий и шаг в файле .feature

singup_page.feature

singup_page.feature

Файл singup_page_steps.ts - описание шага.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 49

Файл singup_page.ts - добавление локатора radio_btn и создание функции selectRadioButton().

singup_page.ts

singup_page.ts

Файл BaseFunctions - cоздание базовой функции selectItem().

BaseFunctions.ts

BaseFunctions.ts

Запуск теста npx cucumber-js --tags=@test4
Результат - тест выполнен успешно.

Результат

Результат

Добавим следующий шаг для проверки выбранного значения.

singup_page.feature

singup_page.feature

Файл singup_page_steps.ts - описание шага.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 54

Файл singup_page.ts - создание функции isRadioChecked().

singup_page.ts

singup_page.ts

Файл BaseFunctions - cоздание базовой функции isChecked().

BaseFunctions.ts

BaseFunctions.ts

Повторный запуск теста npx cucumber-js --tags=@test4
Результат - тест выполнен успешно.

Результат

Результат

Для перепроверки добавим в шаг в табличное значение выбор следующего элемента radio button female.

singup_page.feature

singup_page.feature

В данном случае результатом будет ошибка сообщающая о том, что элемент radio button male не выбран.

Результат

Результат

Сценарий 5 - проверка dropdown поля

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 60

Новый сценарий и шаг в файле .feature

singup_page.feature

singup_page.feature

Файл singup_page_steps.ts - описание шага.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 62

Файл singup_page.ts - создание функции selectDdlValue(). Локатор ddList уже был добавлен ранее.

singup_page.ts

singup_page.ts

Файл BaseFunctions - cоздание функции selectOption()

BaseFunctions.ts

BaseFunctions.ts

Запуск теста npx cucumber-js --tags=@test5
Результат - тест выполнен успешно.

Результат

Результат

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

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

singup_page.feature

singup_page.feature

Повторный запуск теста npx cucumber-js --tags=@test5
Результат - сценарий выполнен успешно.

Результат

Результат

Сценарий 6 - выбор checkbox'a

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 68

Новый сценарий и шаг в файле .feature

singup_page.feature

singup_page.feature

Файл singup_page_steps.ts - описание шага.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 70

Файл singup_page.ts - создание локатора checkbox и функции selectCheckbox().

singup_page.ts

singup_page.ts

Базовая функция selectItem() уже была создана ранее.

Запуск теста npx cucumber-js --tags=@test6
Результат - тест выполнен успешно.

Результат

Результат

Добавление следующего шага для проверки был ли элемент выбран.

Новый сценарий и шаг в файле .feature

singup_page.feature

singup_page.feature

Файл singup_page_steps.ts - описание шага.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 74

Файл singup_page.ts - создание локатора checkbox и функции selectCheckbox().

singup_page.ts

singup_page.ts

Базовая функция isChecked() уже была создана ранее.

Повторный запуск сценария npx cucumber-js --tags=@test6
Результат - сценарий выполнен успешно.

Результат

Результат

Сценарий 7 - проверка ошибки валидации.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 77

Новый сценарий в файле .feature. Используем имеющиеся шаги и создаем новый шаг для нажатия кнопки Submit.

singup_page.feature

singup_page.feature

Файл singup_page_steps.ts - описание шага.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 79

Файл singup_page.ts - создание локатора btn и функции clickButton().

singup_page.ts

singup_page.ts

Файл BaseFunctions - cоздание базовой функции clickBtn().

BaseFunctions.ts

BaseFunctions.ts

Запуск теста npx cucumber-js --tags=@test7
Результат - тест выполнен успешно.

Результат

Результат

Добавление новых шагов - проверка ошибки валидации.

singup_page.feature

singup_page.feature

Файл singup_page_steps.ts - описание шага.

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 84

Файл singup_page.ts - создание локатора valid_error и функции verifyError(). Так же как и в случае с проверкой значения в поле ввода в данной функции присутствует вспомогательная функция для распознавания пути - у какого элемента искать ошибку.

singup_page.ts

singup_page.ts

Файл BaseFunctions - cоздание базовой функции verifyText().

Playwright + Cucumber необычная связка. Практические примеры написания авто тестов - 86

Запуск сценария npx cucumber-js --tags=@test7
Результат - тест выполнен успешно.

Результат

Результат

Добавим в данный сценарий проверку ошибки валидации для поля Last Name - "Required field"

singup_page.feature

singup_page.feature

Повторный запуск теста npx cucumber-js --tags=@test7
Результат - тест выполнен успешно.

Результат

Результат

Изменим текст ошибки для выполнения негативного сценария и перепроверки созданного теста

singup_page.feature

singup_page.feature

В результате получим ожидаемую ошибку. Фактический результат "Please use only alphabetical characters"

Результат

Результат

Заключение

В итоге мы настроили запустили простенький сервер, установили и настроили фреймворк и написали несколько авто тестов. В начале статьи я писал, что обьясню как в моем понимании связка cucumber + playwright может помочь в написании авто тестов начинающему специалисту. При использовании данной структуры и работе в команде опытный специалист может создать основной костяк на основе небольшой части приложения и описав основные операции в файле BaseFunctions. В случаи большого веб приложения и схожих его частей и использовании шагов с универсальными способами, второму специалисту, с меньшим опытом написания авто тестов, будет не сложно покрыть тестами остальную часть приложения на основе имеющегося задела. Как результат это будут созданные фалы для других страниц с дублированием имеющихся операций и минимальными изменениями. Хотелось показать на примере создания тестов для другой страницы, но статья уже получилась не маленькая и я думаю это будет лишним. Так же плюсом будет простота понимания написанных сценариев в файле .feature для технически не подкованного человека.

Это моя первая статья, прошу отнестись с пониманием если имеются неточности или ошибки. Буду рад любой критике. Надеюсь кому-то статья будет полезной. В будущем планирую создать другую статью с практическими тестами для БД или API.

Автор: Aitken

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js