BDD фреймворк для автотестов на Java, использующий:
- Selenide для тестирования Web UI
- Cucumber для написания сценариев в стиле BDD
- REST assured для тестирования REST API
В модуле autotest-web в директории src/main/java/pages находятся классы PageObjects
1.1 Каждый PageObject должен наследоваться от класса WebPage
1.2 Над классом необходимо проставить аннотацию @Name(value = "<имя страницы>")
Пример:
@Name(value = "Главная страница приложения")
public class MainPage extends WebPage {
@Name("Слайдер")
private SelenideElement uuid = $(".slick-track");
}2.1 В классе со степами необходимо наследовать от класса AbstractWebSteps и конструктор класса следующим образом:
public class WebActionSteps extends AbstractWebSteps {
public WebActionSteps(PageManager pageManager) {
super(pageManager);
}
// steps
}- ссылка pageManager хранит в себе инициализированный контекст текущей страницы, с помощью которой можно достать элемент через value аннотации @Name элемента
- При компиляции ссылка pageManager проинициализируется автоматически путем Dependency Injection через PicoContainer
- Более подробно о подходе можно ознакомиться по ссылке Cucumber PicoContainer
2.2 Пример инициализации страницы:
Для того, чтобы получить доступ к элементу, нам необходимо перед этим проинициализировать PageObject
pageName - это value аннотации Name класса PageObject - в нашем примере "Google"
public void setPage(String pageName) {
WebPage page = getPage(pageName);
pageManager.setCurrentPage(page);
}2.3 Теперь страница проинициализирована и получить доступ к элементам можно по его имени (value)
@Если("кликнуть на элемент {string}")
public void clickOnElement(String elementName) {
SelenideElement element = pageManager
.getCurrentPage()
.getElement(elementName);
element.shouldBe(visible).click();
}2.4 Осуществление мягких проверок (SoftAssert)
В конфигурации Selenide есть параметр Configuration.assertionMode, который не отрабатывает должным образом в связке с Cucumber и потому его использование в проекте не допускается.
Для осуществления мягких проверок следует использовать класс ru.lanit.at.assertion.AssertsManager.
Пример использования (Проверка утверждений у SelenideElement)
public static void elementContainsText(SelenideElement element, String text) {
element.execute(Commands.checkSoft(Condition.text(text), Duration.ofSeconds(10)));
}2.5 Расширение и изменения методов SelenideElement с помощью механизма SPI
Если нужно изменить поведение стандартных методов SelenideElement, это можно сделать след образом.
В классе ru.lanit.at.utils.selenide.extensions.CustomCommands, необходимо релизовать свою логику, например код ниже, будет перед осуществлением клика, прикладывать скриншот элемента, на который будет происходить нажатие.
public <T> T execute(Object proxy, WebElementSource webElementSource, String methodName, @Nullable Object[] args) throws IOException {
if(methodName.equals("click")){
addAllureScreenshootElement((SelenideElement)proxy);
}
return super.execute(proxy, webElementSource, methodName, args);
}
private void addAllureScreenshootElement(SelenideElement selenideElement){
AllureHelper.attachScreenShot("Клик на элементе ", selenideElement.getScreenshotAs(OutputType.BYTES));
}Изменения логики формирования Page объектов, осуществляется в классе ru.lanit.at.utils.selenide.extensions.CustomSelenidePageFactory. С помощью этого класса можно расширить/изменить логику инициализации элементов.
3.1 Написание сценариев
#language:ru
Функционал: Поиск гугл
Сценарий: Открытие страницы google.com, ввод значения в поиск
* открыть браузер
* инициализация страницы "Google"
* ввести в поле "поле поиска" значение "Погода в Москве"
* на странице имеется элемент "результаты поиска"
* кликнуть на элемент "кнопка поиска"
* инициализация страницы "страница результатов поиска"
* на странице присутствует текст "Погода в Москве"- Шаг 1 - открытие веб страницы
- Шаг 2 - инициализация PageObject через его value аннотации @Name
- Шаг 3 - как в примере 2.3 получаем текущий элемент по его value аннотации @Name и производим действия/проверки
3.2 Сценарии из фрагментов Начиная с версии 1.2, фреймворк поддержиивает напиисание сценариев из фрагментов. Фрагменты должны храниться в директории "fragments" в корне проекта в файлах с расширением *.feature. Каждый фрагмент должен быть выделен в отдельный сценарий и аннотирован @fragment
@fragment
Сценарий: открытие виджета
* на странице имеется элемент "кнопка поиска"
* кликнуть на элемент "кнопка поиска"
* переход на страницу "Google страница результатов"
* на странице имеется элемент "виджет погоды"Чтобы использовать фрагмент, в сценарии следует добавить шаг вида
* вызвать фрагмент "открытие виджета"Передаваемый текстовый параметр шага должен соответвовать имени сценария, содержащего фрагмент. Перед запуском тестов,
фреймворк анализирует содержимое всех фича-файлов и заменяет шаг * вызвать фрагмент"{string}" на группу шагов из
соотвествующего фрагмента.
!IMPORTANT!
Чтобы функционал работал корректно, компиляцию проекта необходимо выполнять при помощи команды mvn compile.
Для запуска фич по отдельности через функционал или отладчик IDEA внесите измение в шаблон конфигураци Cucumber:
Run/Debug Configurations/ Edit configurations template / Cucumber Java / Build Добавить действие Maven "compile"
Для запуска фрагментов через Maven дополнительных настроек не требуется.
В директории autotest-web/src/test/resources/config имеются примеры config-файлов для разных браузеров и общих настроек запуска.
configuration.properties
stand= названия стенда для тестирования в классе (ru.lanit.at.utils.Stand) содержатся адреса стендов
screen_after_step=false - необходимость прикреплять скриншот к каждому шагу
baseUrl=https://petstore.swagger.io/v2/ - базовый url для апи запросов
remoteUrl=127.0.0.1:4444 - адрес удаленного хаба/selenoid.
enableVNC=true - возможность отображения работы теста в браузере, переменная применима только selenoid.
enableVideo=true - возможность записывать видео, переменная применима только selenoid.
enableLog=true - флаг для сохранения логов selenoid контейнера, переменная применима только selenoid.
chrome.properties
webdriver.browser.size=1920x1080 - разрешение браузера
webdriver.browser.name=chrome - название браузера
webdriver.timeoutSeconds=4 - таймаут ожидания состояния веб-элементов
polling.timeoutMs=200 - периодичность опроса веб-элемента
webdriver.version=91.0 - версия веб-драйвера
Так же с помощью одноименных переменных окружения можно переопределить данные настройки
Драйвера скачиваются с помощью WebDriverManager, учитывайте это если находитесь в закрытом контуре
Шаг 1. Конфигурируем запрос с помощью шага
* создать запрос
| method | path | body | url |Если какой то из столбцов не указан в данном шаге, то он не учитывается в запросе Например:
* создать запрос
| method | path | body |
| POST | /user | createUser.json |
ИЛИ
* создать запрос
| method | path | body |
| POST | /user | {<тело запроса>} |
ИЛИ
* создать запрос
| method | url |
| GET | https://petstore.swagger.io/v2/user/<username> |- Можно указать basePath через одноименную системную переменную или в файле конфигурации configuration.properties. Тогда вместо столбца url можно указывать просто path. И наоборот, если указать столбец url с полным url хоста и path то basePath не учитывается, даже если указан с системных переменных.
- Тело запроса - в качестве тела можно передать в таблицу, как просто текст, так и название файла json, которое будет лежать по пути autotest-rest/src/test/resources/json
Шаг 2. Добавление Headers и Query
* добавить header
| Content-Type | application/json |
* добавить query параметры
| city | Moscow |Шаг 3. Отправка запроса
* отправить запросШаг 4. Проверка ответа
* статус код 200Если необходимо проверить тело ответа, то данные можно вытащить с помощью jsonpath. Значение сохранится в переменную из столбца 1
* извлечь данные
| user_id | $.message |Проверить извлеченные данные можно с помощью шага:
* сравнить значения
| ${user_id} | != | null |
ИЛИ
| ${user_id} | == | 1234567890 |
ИЛИ
| ${user_id} | > | 0 |
ИЛИ
| ${user_id} | < | 100 |
ИЛИ
| ${user_id} | содержит | qwerty123 |С помощью следующего шага можно сгенерить переменные для последующего использования в тесте
* сгенерировать переменные
| id | 0 |
| username | EEEEEEEE |
| firstName | EEEEEEEE |
| lastName | EEEEEEEE |
| email | EEEEEEE@EEEDDD.EE |
| password | DDDEEEDDDEEE |R - случайная русская буква
E - случайная английская буква
D - случайное число
Другие символы в строке игнорируются и остаются неизменяемыми
Сгенерированные значения хранятся в контексте теста. Их можно подставлять в запросы, тела запросов. Достать их можно используя синтаксис ${username}
mvn clean test -Ddataproviderthreadcount=4 -Dscreen_after_step=false -Dtags="@authentication"-
-Ddataproviderthreadcount=4 - кол-во поток выполнения, значение по умолчанию 1 поток (Изменение дефолтного кол-ва поток производится в файле src\test\resources\suite.xml)
-
-Dscreen_after_step=false - Автоматическое снятие скриншотов после каждого шага. Дефолтное значение =false (Изменение дефолтного значения производится в файле src\test\resources\config\configuration.properties)
-
-Dtags="@authentication" - Выбор тестов с определенным тегом. Дефолтное значение отсутствует, т.е. если в запуске не указывать данный параметр то, будет запущены все фичи файлы.
Тажке в командную строку можно передать любой параметр из файлов *.properties Для добавление нового параметра, его нужно будет прописать в соответствующем .properties файле и добавить соответствущий полю getter в java классе.
mvn clean test Так же запустить тесты можно через плагин Cucumber (предварительно установив его в Idea), для этого необходимо открыть любой feature-файл, и кликнуть по зеленой стрелке рядом со стройкой Функционал или Сценарий

По итогу прогонов можно сгенерить Allure отчет, для этого необходимо в Intellij Idea кликнуть на строку Maven в правом верхнем углу IDE и следовать инструкции по пунктам ниже:
В п.1 необходимо выбрать тот модуль, в котором запускались тесты.

По итогу сформируется Html страница с отчетом.

В отчете можно провалиться в каждый шаг и посмотреть информацию по нему

где
- Зеленым цветом отмечены - успешно прошедшие тесты
- Желтым цветом отмечены - тесты в которых есть неблокирующие дефекты
- Серым цветом отмечены - тесты который были пропущены
- Красным цветом отмечены - тесты с блокирующим дефектом
Шаги с неблокирующими дефекты помечаются в отчете желтым цветом. По окончании теста отображается информация о всех подобных дефектах.