Top.Mail.Ru

Автотесты для сайта на Java с нуля

Что нужно знать, чтобы начать писать автотесты на Java

Что такое UI автотесты

UI (user interface, «пользовательский интерфейс») - это то, что мы видим глазами, когда заходим на сайт: иконки, кнопки, картинки и т.д.

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

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

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

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

Компания Software Cats уже более пяти лет занимается аутстафом и аутсорсом по направлениям

Если у вас есть ИТ-проблема, оставьте ваши контакты, и мы поможем составить план ее решения.

С чего начать. Тест-дизайн

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

В общем случае базовая структура автотеста будет выглядеть следующим образом:

  1. Подготовка окружения
  2. Поиск нужных элементов на странице
  3. Совершение действия/ий с элементами
  4. Проверка результата
  5. Освобождение ресурсов

Давайте рассмотрим на примере, чем тест-кейс для автоматизированного тестирования отличается от тест-кейса для ручного тестирования.

Для примера, будем использовать простую формочку с нашего сайта -> https://softwarecats.dev

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

Кейс для ручного тестирования этой формы будет выглядеть так:

Предусловия:

Открыта форма “Обсудить проект”.
Есть кнопка “Отправить заявку”.

Шаги:

  1. Заполнить форму.
  2. Нажать кнопку “отправить заявку”

Ожидаемый результат:

Показано сообщение об успешной отправке заявки.

Для полной уверенности нам следовало бы еще убедиться в том, что
  • от сервера получен ответ 200 ОК,
  • данные из формы занесены в соответствующие таблицы в БД,
  • на email администратора пришло письмо с данными формы.
Но поскольку мы тестируем UI, то считаем, что появление сообщения об успешной отправке заявки является гарантом того, что сообщение действительно отправлено (и доставлено). По этой же причине мы пренебрежем постусловиями т.е. освобождением ресурсов - в идеале нам следовало бы удалить тестовые данные, которые мы вводили в форму, из базы данных.

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

Давайте перепишем этот тест так, как мы будем “говорить” программе, что нужно делать.

Предусловия:

  1. Открыть сайт https://softwarecats.dev в браузере Chrome (можно указать любой другой браузер, если проверка именно в нем важна)
  2. Найти на странице кнопку “Обсудить проект”
  3. Нажать на кнопку “Обсудить проект”

Шаги теста:

  1. Найти на странице поле “Как вас зовут?”
  2. Поставить курсор на поле “Как вас зовут?”
  3. В поле “Как вас зовут?” ввести значение. Ограничения на количество символов нет, только кириллица и латиница, строчные и заглавные буквы.
  4. Найти на странице поле “Любой удобный контакт”
  5. Поставить курсор на поле “Любой удобный контакт”
  6. В поле “Любой удобный контакт” ввести значение. Ограничения: на количество символов нет, кириллица и латиница, строчные и заглавные буквы, цифры, спецсимволы.
  7. Найти на странице поле “Что вы хотите обсудить?”
  8. Поставить курсор на поле “Что вы хотите обсудить?”
  9. В поле “Что вы хотите обсудить?” ввести значение. Ограничения на количество символов нет, ограничения на значение поля нет.
  10. Найти на странице кнопку “Отправить заявку”
  11. Нажать на кнопку “Отправить заявку”

Ожидаемый результат (проверить что):

Показано всплывающее окно с текстом “Спасибо! Данные успешно отправлены.”

Дальше дело техники - нужно правильно написать на Java шаги теста и проверку ожидаемого результата.

Настройка окружения

Код тестов мы будем писать на Java в среде разработки IntelliJ IDEA. Для этого необходимо установить все нужные компоненты.
Установка JAVA

Если у вас еще не установлена Java, то нужно скачать и установить JDK (это бесплатно) со старого доброго сайта Oracle -> https://www.oracle.com/java/technologies/downloads/#jdk19-windows


JDK (Java Development Kit) - это набор инструментов для разработки на Java. В него входят все необходимые компоненты, которые в том числе позволяют компилировать и запускать написанный код.

Для этого нужно:

  1. Убедится, что ваша система 64-разрядная:
  2. Пуск -> Параметры -> О системе.
  3. Убедиться, что Java еще не установлена (или уже установлена): открыть консоль/терминал Windows (Поиск -> cmd), набрать java -version и нажать Enter. Если Java установлена, то отобразится версия Java, если нет, то отобразится соответствующее сообщение.
  4. Перейти по ссылке на сайт Oracle и скачать Java.
  5. Инсталлировать Java, следуя инструкциям установщика.
  6. Прописать путь к JDK в системные переменные JAVA_HOME и Path. Поиск: изменение системных переменных среды. В открывшемся окне перейти в “Переменные среды”, нажать “Изменить” и прописать путь до JDK в системные переменные JAVA_HOME и Path.
  7. После этого шага понадобится перезагрузка.
8. Убедится, что Java установлена.

Еще один способ установить Java - это скачать готовый пакет Amazon Corretto -> https://aws.amazon.com/ru/corretto/ В этом случае системные переменные пропишутся автоматически.
Установка IntelliJ IDEA
IntelliJ IDEA - это среда разработки программного обеспечения, в которой разработчики и автотестировщики пишут код. В ней есть умный редактор, навигация, подсказки, в нее интегрированы все необходимые инструменты для сборки и публикации.

Бесплатную версию Community Edition можно скачать с официального сайта JetBrains -> https://www.jetbrains.com/ru-ru/idea/download/#section=windows

Запустить установку и следовать инструкциям, на шаге Installation Options отметить все пункты в разделе Create Associations: это расширения файлов, которые по умолчанию будут открываться в IDEA.
Установка Maven
Maven - это система управления проектом, которая используется для загрузки всех необходимых компонентов, установки параметров тестирования, запуска тестов, сбора базовой информации о результатах тестирования.

Скачать Maven можно с официального сайта https://maven.apache.org/download.cgi
Нужно скачать и распаковать zip-архив, путь до папки bin распакованного архива нужно добавить в переменную окружения Path по аналогий с JDK.

Проверить, что Maven устанавлем можно консольной командой mvn -v. Если все верно - отобразится версия Maven.
Установка Git
Скачать и установить Git с официального сайта -> https://git-scm.com/download/

Запустить установщик, при установке обязательно отметить галочку для установки GitBash - это приложение, эмулирующее работу командной строки Git, оно необходимо для полноценной работы с Git. Также необходимо поставить галочку “Использовать Git из командной строки”.

Чтобы убедиться, что Git установлен, запроси информацию о программе:
В терминале Winows ввести git --version (по аналогии с проверкой установки Java).

Чтобы при совместной работе над проектом коллеги смогли понять какие из изменений твои, необходимо в конфиге Git указать информацию о себе.

Для этого в терминале Windows нужно ввести свои данные - имя и email, используя команду git config --global:

git config --global user.name "My Name"
git config --global user.email me@email.mail
Теперь нужно проверить, что всё получилось: в терминале Windows выполнить команду git config --list

Среди прочих свойств будут и заданные данные: user.name и user.email.

Подготовка проекта

Чтобы создать проект, нужно запустить IDEA, перейти в меню File -> New -> Project.

В открывшемся окне нужно ввести название проекта, выбрать язык (Language), на котором будем писать код - Java, а также выбрать систему сборки (Build system) и указать какой JDK будем использовать (JDK). После этого нажать кнопку Create. Проект создан.
Теперь развернем в левом меню IDEA дерево файлов проекта, и развернем папку src. Это именно та папка, где будут хранится файлы проекта (в папке main -> java) и файлы тестов (test -> java).
Вот и все! Теперь мы готовы к написанию автотестов!

Краткая справка по Git. Коммиты, ветвление, мерж

Чаще всего над программным продуктом работает не один человек: кто-то пишет один модуль, еще кто-то другой, тесты могут писать совсем другие люди, не те, кто пишет основной код и т.д.. Чтобы хранить код удаленно и совместно работать над ним используются специальные сервисы, например GitHub или GitLab.

Одна из главных функций в этих сервисах - отслеживать изменения в файлах.

"Под капотом" у них - специальная утилита - Git - для отслеживания истории изменения файлов. С помощью Git вы можете откатить проект до более старой версии, сравнивать изменения в версиях проекта, объединить все изменения и тд.
Репозитории
Хранилище вашего кода/файлов (и истории его изменений) называют репозиторием.

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

Создадим локальный и удаленный репозитории и свяжем их между собой.

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

Для этого нужно перейти в папку проекта, правой кнопкой мыши открыть меню и запустить Git.
Откроется командная строка в которой нужно ввести и запустить команду git init. После чего Git сообщит, что репозиторий инициализирован.
Теперь git будет отслеживать изменения в файлах этого репозитория, но чтобы это произошло git’у нужно сообщить, какие именно файлы нужно отслеживать.
Статусы файлов, коммит
В Git есть несколько статусов файлов:

  • Untracked - файл, который Git пока не “видит” т.е. не отслеживает.
  • Unmodified - файл, который Git уже видит, но файл еще не изменялся.
  • Modified - это файл, в который вносились изменения (сам файл отслеживается Git’ом, но изменения пока не зафиксированы).
  • Staged - это файл, добавленный в индекс т.е. готовый к коммиту (сохранению).

Как только файл будет закоммичен т.е. все изменения зафиксированы Git’ом, он снова переходит в статус unmodified.

Когда в инициализированном репозитории появляется новый файл, он автоматически попадает в состояние untracked, файл можно изменять, но Git не будет учитывать изменения. Чтобы Git “увидел” файл, его нужно добавить в индекс и тогда файл перейдет в состояние Staged.

Чтобы узнать какие файлы в каком состоянии находятся используется команда git status.
Видим, что Git показывает список не закоммиченых файлов и предлагает добавить файлы в индекс, с помощью команды git add название_файла. Можно добавить все файлы сразу, с помощью команды git add --all.

Выполняем команду. Теперь видно, что все файлы в репозитории готовы к коммиту.
Чтобы сохранить изменения в файле т.е. закоммитить файл, нужно дать Git команду git commit c ключом -m (англ. message), после ключа обычно указывают комментарий, в котором указывают, что именно изменилось в файле: git commit -m "My first commit".
Чтобы посмотреть список коммитов используется команда git log.

Как найти нужный коммит в истории, как посмотреть его, как откатить проект до определенной версии и многое другое можно изучить, воспользовавшись официальной документацией Git https://git-scm.com/doc.
Ветвление
Еще одна важная функция git, которая нам понадобится - это ветвление. Ветвление - это параллельная разработка по нескольким линиям т.е. разделение версий проекта и работа над ними по отдельности.

Когда репозиторий инициализируется командой git init, автоматически создается основная ветка. Обычно она автоматически называется master (иногда main) и в ней находится основная стабильная версия проекта.

Командой git branch можно посмотреть в какой ветке ты сейчас находишься.
Чтобы не испортить в процессе разработки тестов основную ветку, создают вторую ветку и работают уже с ней, назвать ее можно как угодно. Чтобы создать ветку используют команду git branch название_ветки.
Однако, после создания новой ветки, мы все еще находимся в основной ветке проекта. Чтобы переключится на вновь созданную ветку (или на любую другую) используется команда git checkout название_ветки. Либо используют ключ -b, чтобы переключится на ветку сразу после ее создания git checkout -b название_ветки.
Мерж
Чтобы слить (мёрджить, от англ merge - слияние) ветки между собой используется команда git merge [название ветки, которую присоединяют к текущей].

В разных компаниях по разному принято мержить в основную (master) ветку в удаленном репозитории проекта. Кто-то делает это самостоятельно, а где-то этим занимается ведущий тестировщик/разработчик только после ревью написанного кода. Но про это немного позже. А подробнее про merge, а так же про разрешение конфликтов, которые могут возникать в процессе слияния веток, можно почитать в документации git.

GitHub

Локальный и удаленный репозитории
Мы научились работать с git в локальном репозитории. Удаленные репозитории хранят в Интернете и используют для этого сервисы GitHub или GitLab.

Давайте взглянем на GitHub - это сервис для совместной разработки, в нем можно завести аккаунт и разместить свой код, а также совместно работать над любыми проектами.

Для этого нужно завести аккаунт и авторизоваться GitHub - тут все предельно просто.

Теперь нужно создать удаленный репозиторий. Для этого нужно перейти во вкладку Repositories и нажать New.
В открывшемся окне создания нового репозитория необходимо ввести его имя, а также пометить репозиторий как Public, если хотите, чтобы любой пользователь GitHub мог увидеть репозиторий. Так же отметим чек бокс для автоматического создания файла README.md - это инструкция к проекту, в котором с помощью специальной разметки, описывается, как пользоваться проектом. Подробнее можно посмотреть в документации.
Осталось нажать Create repository. Готово! Удаленный репозиторий создан и он пока пуст.

Чтобы связать локальный репозиторий с удаленным нам понадобится ссылка на удаленный репозиторий, она находится во вкладке Code.
Перейдем в папку проекта и запустим git. Ранее мы уже инициализировали локальный репозиторий, сделали первый коммит и создали отдельную ветку для разработки наших тестов. Но пока это все хранится только локально на компьютере. Чтобы проект был доступен удаленно и все изменения поступали в удаленный репозиторий, нужно связать репозитории между собой. Для этого используется команда git remote add origin URL_удаленного_репозитория.
Чтобы проверить, что репозитории связались, используется команда git remote -v
Теперь нужно передать файлы из локального репозитория в удаленный, для этого нужна команда git push.
Теперь мы видим в удаленном репозитории файлы и ветки нашего проекта.
Откроем проект в IDEA и перейдем во вкладку git, если нажать Share Project on GitHub,то IDEA выдаст предупреждение, что проект уже связан с удаленным репозиторием на GitHub.
Также в IDEA мы можем отслеживать состояние проекта, а так же использовать все основные команды git прямо из IDE.
Другой способ создания локального репозитория - сначала создать удаленный репозиторий с помощью GitHub/GitLab, а потом командой git clone скопировать его с сервера - подробнее в документации.
Pull Request
Нельзя просто так взять и залить свой код в master (стабильную версию проекта). Код должен пройти проверку. Для этого и создается pull request - это запрос на то, чтобы код объединили с основным. Чтобы создать пул-реквест нужно перейти в удаленный репозиторий, в ту ветку, в которую был последний пуш и которую необходимо залить в мастер.

Нажать кнопку Compare & pull request, заполнить название и описание, нажать кнопку Create pull request. Этот пул-реквест получит владелец репозитория для проверки. Здесь же, во вкладке Conversation можно обсудить изменения и необходимые правки. После ревью пул-реквеста код либо мержат в master, если предлагаемые изменения приняты, либо пул-реквест закрывается, если изменения не приняты.

Подключение библиотек

Откроем в IDEA ранее созданный проект и вспомним его структуру.
Обратим внимание на файл pom.xml (POM – Project Object Model) - это специальный XML-файл, который хранится в базовой директории проекта и содержит информацию о проекте, различных деталях конфигурации, библиотеках, плагинах и тд, которые используются Maven для создания проекта.

Для начала заполним данные о проекте <groupId>имя_пакета</groupId>
<artifactId>название_программы</artifactId>
<version>версия_программы</version>

Теперь подключим библиотеки.
Библиотека - это готовое решение, которое мы можем использовать при написании наших программ.

Как правило, большинство популярных библиотек находятся в центральном репозитории Maven, где можно найти нужную библиотеку и посмотреть как она подключается. Кстати в Maven библиотеки называются зависимостями.
Чтобы добавить зависимость, в файле pom нужно: создать блок
<dependencies></dependencies>, в котором будут хранится все зависимости; каждая зависимость объявляется внутри блока <dependencies> в тэге <dependency></dependency>.

Для написания UI тестов нам понадобятся зависимости JUnit и Selenium, Selenide:

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>com.codeborne</groupId>
<artifactId>selenide</artifactId>
<version>5.23.2</version>
</dependency>
</dependencies>

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

Способы поиска элементов на странице

Прежде чем перейти к написанию кода, давайте вспомним с чего мы начинали написание автотеста, а именно тест-дизайн.

В шагах итогового сценария присутствуют шаги, начинающиеся со слов “Найти на странице поле/кнопку”. То есть, прежде чем совершать какие-то действия с элементом на странице (заполнять поле, нажимать кнопку и тд) нужно этот элемент на странице найти.

Для этого используются локаторы - это запросы, которые ищут элементы страницы по их характеристикам (например, по тексту, по классу или по id).

Локаторы могут находить один элемент, например, кнопку “Войти” или несколько, например, все ссылки на странице.

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

Один из наиболее популярных способов поиска элементов на странице это XPath. Именно его мы будем в дальнейшем использовать в наших автотестах.

XPath — это язык, на котором можно написать запрос, который поможет найти любой элемент на странице путем описания пути до него.

Путь до элемента можно задавать по разному.
Абсолютный путь до элемента
Абсолютный путь до элемента - это полный путь от корневого элемента до целевого. Например, путь до логотипа компании в хедере страницы будет выглядеть так: html/body/div/header/div[3]/div[2]/div/div/a/img
Этот способ не является оптимальным, поскольку любое изменение верстки страницы приведет к тому, что элементы по таким локаторам не будут найдены. Поэтому используется другой способ.
Поиск элементов по атрибутам
Можно искать элемент по любому из его атрибутов, но лучше выбрать какой-то уникальный атрибут - атрибут значение которого единственное на странице, например, только на одной кнопке на странице написано “Обсудить проект”. Но чаще всего такой атрибут - это id.

Синтаксис поиска элемента по id будет такой $xpath("html/body/div[@id='1']").

Часто испрользуется поиск элементов с использованием относитьельного пути и атрибутов. Весь путь до корневого элемента заменяется символами .//. Например, для ссылки пункта меню “О компании” запрос получится таким: $xpath(".//a[contains(text(),'О компании')]").

Более подробно про xpath можно почитать тут.

Кроме того, для большинства популярных браузеров существуют специальные плагины, которые помогают работать с локаторами xpath.

—note—
Кроме xpath, другим популярным методом поиска элементов на странице является поиск по css. В данном случае применяют CSS-селекторы - это специальные выражения, которые указывают на тот или иной элемент на странице. Например, [class='logo'] - найти элемент, у которого значение атрибута class = logo. Более подробно тут.


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

Потренироваться искать элементы страницы с помощью xpath или css можно используя инструменты разработчика браузера.
Например, чтобы найти кнопку “Оставить заявку” на главной странице сайта Softwarecats нам понадобится такой xpath-локатор: $xpath(".//a[contains(text(),'Оставить заявку')]").

Нужно ввести его в строку поиска в консоли браузера и если локатор составлен правильно, элемент будет найден.

Так.
Или так.
Часто приходится работать со сложными случаями: найти несколько элементов, выбрать только определенные элементы из списка, найти скрытые элементы и т.д. Главное не боятся и использовать все возможности xpath для составления локторов.

Google и немного упорства, и я уверена - все получится. А вот здесь можно посмотреть несколько примеров.

Как написать автотест на Java, используя Selenide

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

Уже готовый проект вы можете посмотреть на гитхабе.

Selenium. Selenium WebDriver

Selenium - это набор инструментов для автоматизации веб-браузеров. Он позволяет создавать тесты для веб-приложений, имитируя действия пользователя.

Selenium WebDriver - это один из инструментов Selenium, специальный драйвер, который позволяет управлять браузерами с помощью API. Он поддерживает большинство современных браузеров (Chrome, Firefox, Safari и др.). Другими словами он позволяет совершать действия с найденными элементами, например, открыть страницу, кликнуть по ссылке, поставить курсор в какое-то поле, нажать кнопку на странице и т.д. Подробнее с ним, а также с другими инструментами Selenium можно познакомится на официальном сайте.

Настройка среды для тестирования

Чтобы в коде реализовать методы Selenium, предварительно нужно настроить среду для тестирования.

Для примера договоримся, что мы будем писать тесты для браузера Chrome. Для других браузеров все делается аналогично.

Подготовим среду для запуска тестов, для этого нужно:

1. Скачать драйвер ChromeDriver, который соответствует версии вашего браузера Chrome, с официального сайта ChromeDriver. После скачивания и распаковки архива, вы получите исполняемый файл chromedriver.exe. Запомните путь до драйвера, он нам понадобится в тестах.

2. Добавить необходимые зависимости в файл pom.xml, основные зависимости мы добавили ранее, если нам понадобятся дополнительные - мы добавим их по ходу написания теста.

3. Создать тестовый класс, в котором мы будем писать код теста.
4. Импортировать необходимые классы, для работы с драйвером.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver; 
5. В тестовом классе создать метод setUp() и аннотировать его как @Before, что означает, что этот метод будет выполняться перед каждым тестом.

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

Не забудьте импортировать необходимые аннотации JUnit . Тут мы забежим немного вперед и импортируем сразу четыре: @Before, @Test, @After и assertEquals.

6. В методе setUp() установить системное свойство для указания пути к chromedriver.
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
Обратите внимание, что в указании пути используется символ “/”, а не “\”.

7. Инициализировать драйвер и создать экземпляр драйвера.
WebDriver driver = new ChromeDriver();
8. Напишем сразу же и метод, который будет аннотирован как @After, что означает, что этот метод будет выполняться после каждого теста. Этот метод будет закрывать браузер после теста.

Напишем тест

Теперь напишем непосредственно код теста, который будет, используя веб-драйвер, открывать страницу https://www.google.com/ и проверять, что заголовок страницы соответствует ожидаемому значению с помощью assertEquals - метода, предоставляемого JUnit, который используется для проверки того, что два значения равны. Подробнее про методы JUnit можно почитать все там же - на официальном сайте JUnit.

Для обозначения тестового метода будем использовать аннотацию @Test, а в теле тестового метода будем использовать метод Selenium driver.get("https://www.google.com"). Этот метод открывает веб-страницу в браузере, которым управляет WebDriver.
Попробуйте запустить тест. На этом этапе возможно возникновение ошибок, связанных с отсутствием или несовместимостью версий библиотек. Например, это может быть связано с неправильной или отсутствующей версией Selenium. Или chromedriver.

Несовместимые зависимости обычно подсвечены в IDEA в файле pom.xml
Чтобы исправить эту ошибку, нужно найти в репозитории Maven актуальные зависимости и исправить их в файле pom.xml.

После этого пересоберите проект.
И запустите тест. Если все зависимости указаны правильно, тест запустится - вы увидите, как chromedriver открыл браузер и перешел на страницу google.

А тест стал зеленым, это значит, что проверка заголовка прошла успешно.
Поздравляю, первый тест на Java написан!
Lля того, чтобы немного закрепить работу с локаторами и чтобы проще было двигаться дальше, давайте добавим в наш тест код, который будет искать результаты, например, для запроса “Selenium WebDriver”.

Но для начала давайте вспомним самое начало, а именно - вспомним про тест-дизайн и запишем последовательность шагов для автотеста:

  • Найти нужные элементы на странице: для нашего теста таких элементов два - поле для ввода текста и кнопка, которая запускает поиск.
  • Ввести текст в поле поиска.
  • Нажать кнопку поиска.
Для начала дадим веб-драйверу команду найти нужные элементы на странице с помощью xpath и поместить их в соответствующие объекты.

Поле для ввода текста для поиска:
WebElement searchField = driver.findElement(By.xpath("//textarea[@id='APjFqb']"));

Кнопка поиска:
WebElement searchButton = driver.findElement(By.xpath("(//input[@name='btnK'])[2]"));

Далее - ввод текста в поле поиска и клик по кнопке поиска.
searchField.sendKeys("Selenium WebDriver");
searchButton.click();

Selenide
Selenide - это популярный фреймворк, который упрощает написание автотестов. Как минимум, нужно будет написать меньше кода, и код будет проще. Подробные примеры использования можно посмотреть в репозитории Selenide.

Давайте перепишем наш тест с использованием Selenide.

Не забудьте подключить Selenide к проекту, если еще не сделали этого.
<dependency>
   <groupId>com.codeborne</groupId>
   <artifactId>selenide</artifactId>
   <version>7.3.3</version>
</dependency>
Еще один приятный бонус Selenide не только сам запускает драйвер, но закрывает браузер, дополнительный метод не нужен.

Давайте сравним код, написанный с использованием Selenium WebDriver и с использованием Selenide.

Вот насколько меньше кода нужно писать с использованием Selenide.
Основные методы, которые мы будем использовать:

  • Чтобы открыть страницу: open("https://www.google.com"); //открыть страницу
  • Чтобы найти элемент на странице ($ - здесь просто алиасы для соответсвующих команд): find(By) / $(By) //найти элемент по id, имени, тэгу и так далее

Например поиск по xpath будет иметь такую запись: $(byXpath("//textarea[@id='APjFqb']"))

  • Чтобы ввести значение в поле: setValue("Selenium WebDriver");
  • Чтобы кликнуть по элементу: click();
  • А также некоторые другие…

Посмотреть другие методы и способы поиска элементов можно все там же, в репозитории Selenide.

Также нам понадобятся методы проверки и сравнения фактического результата с ожидаемым.
Например, мы ожидаем увидеть результаты в области, предназначенной для вывода результатов поиска.
$(byXpath("//div[@id='search']")).shouldBe(visible);

Вот полный код все того же теста, написанного на Selenide.

Для упрощения здесь я заменила поиск кнопки поиска и клик по ней нажатием Enter на клавиатуре - pressEnter();

import org.junit.Test;
import static com.codeborne.selenide.Condition.visible;
import static com.codeborne.selenide.Selectors.byXpath;
import static com.codeborne.selenide.Selenide.*;

public class SelenideTestClass {

   @Test
   public void test() {
       open("https://www.google.com");
       $(byXpath("//textarea[@id='APjFqb']")).setValue("Selenium WebDriver").pressEnter();
       $(byXpath("//div[@id='search']")).shouldBe(visible);
   }
}
Еще одна довольно удобная особенность Selenide - это то, что в методы, которые помогают взаимодействовать с элементами, уже встроены неявные ожидания. Методы ждут, пока элементы не станут видимыми.

По умолчанию, величина таймаута - 4000 миллисекунд. Например, вместо $("#submit").shouldBe(visible).click() можно сразу писать $("#submit").click() - Selenide подождёт, когда кнопка появится на экране без дополнительных указаний.

Проверки также можно использовать в качестве явных ожиданий - чтобы дождаться нужного состояния элемента перед действием.

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

Например, так:
shouldBe(visible, Duration.ofSeconds(8)) //ждать, пока веб-элемент не станет видимым, в течение 8с

Рage Object Model

Мы уже написали свои первый тест. Давайте посмотрим на тестовый класс еще раз.
public class SelenideTestClass {

   @Test
   public void test() {
       open("https://www.google.com");
       $(byXpath("//textarea[@id='APjFqb']")).setValue("Selenium WebDriver").pressEnter();
       $(byXpath("//div[@id='search']")).shouldBe(visible);
   }
}
Здесь мы в одном классе и искали элементы, используя xpath и взаимодействовали с элементами и проверяли полученный результат.

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

Чтобы этого избежать и вносить минимум изменений в код при изменениях на странице, используют паттерн проектирования (написание кода по особым правилам), который называется Page Object Model, или POM.

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

Давайте сразу посмотрим на примере. Для этого в нашем проекте в пакете main/java создадим отдельный пакет для хранения классов страниц и в нем создадим класс GoogleMainPage, в которм и опишем главную страницу Google.
В Selenide для взаимодействия с веб-элементом нужно создать объект класса SelenideElement.

В Selenide мы можем использовать аннотации Selenium, в частности @FindBy для поиска элементов на странице.

Код класса будет выглядеть так

Base Test

Теперь напишем сам код теста.

Здесь, так же как и до этого, когда мы писали тест, используя Selenium, какие-то общие действия, которые нужно совершать перед тестами и после них, можно внести в аннотации @Before и @After или даже правильнее будет - в отдельный класс BaseTest, в котором уже использовать аннотации. Сами тестовые классы в этом случае будут наследниками класса BaseTest.

Test

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

При написании тестов принято давать тестовым классам такие имена, чтобы они отражали тестируемую функциональность и заканчивались суффиксом Test. А имена тестовых методов должны описывать проверяемое поведение и начинаться с префикса test.

Для улучшения читаемости кода используем еще одну аннотацию из библиотеки JUnit, с помощью которой можно озаглавить тест.

@DisplayName("Получение поисковой выдачи")

Проверка результатов

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

Здесь как раз и нужно определится, чего мы ожидаем. Например,
- осуществляется ли в принципе поиск после ввода текста в поле и нажатия Enter;
- есть ли результаты поиска;
- релевантны ли результаты поиска.

Следуя классическим канонам проектирования тестов - один тест=одна проверка - нам бы следовало написать 3 теста, но поскольку эти проверки логически связаны и относятся к одному сценарию, мы объединим их в одном тесте.

Посмотрим на страницу до поиска и после поиска.

До осуществления поиска
После поиска
Мы видим, что результаты поиска отображаются в div c id="search"//*[@id="search"]. До поиска такого блока на странице не было. Поэтому для проверки “осуществляется ли в принципе поиск после ввода текста в поле и нажатия Enter” достаточно проверить его наличие на странице после поиска.

Для проверки “есть ли результаты поиска” достаточно даже одного результата. Поэтому проверим есть ли на странице первый результат - это мы можем сделать по заголовку.

Чтобы проверить релевантность поиска, нужно пробежаться по результатам поиска и выяснить, есть ли среди них такие, где встречается текст Selenium WebDriver.

Вернемся в page object страницы - класс GoogleMainPage и допишем соответствующие методы и локаторы.
//Локатор для блока с результатами поиска
@FindBy(how = How.XPATH, using = "//div[@id='search']")
private SelenideElement results;

// Локатор заголовка первого результата поиска
@FindBy(how = How.XPATH, using = "//h3")
private SelenideElement firstResult;

//Локатор для получения всех заголовков результата поиска
@FindBy(how = How.XPATH, using = "//div[@id='search']//h3")
private ElementsCollection resultTitles;

//Метод проверки поиска
public boolean isResult() {
   return results.isDisplayed();
}
//Метод проверки показа первого результата в поиске
public boolean isFirstResult() {
   return firstResult.isDisplayed();
}
// Метод для получения заголовков из коллекции
public List<String> getResultTitles() {
   List<String> titles = new ArrayList<>();
   for (SelenideElement title : resultTitles) {
       titles.add(title.getText());
   }
   return titles;
}
Теперь перейдем в тестовый класс и допишем необходимые проверки.
//ПРОВЕРКИ

//Осуществился ли поиск
assertTrue("Поиск не осуществился", googleMainPage.isResult());

//Есть ли результаты поиска
assertTrue("Отсутствуют результаты поиска", googleMainPage.isFirstResult());

//Релевантность поиска
boolean relevantResults = false;
for (int i = 0; i <= googleMainPage.getResultTitles().size(); i++) {
   String currentTitle = googleMainPage.getResultTitles().get(i);
   if (currentTitle.toLowerCase().contains("selenium") || currentTitle.toLowerCase().contains("webdriver")) {
       relevantResults = true;
       break;
   }
}
assertTrue("Результаты поиска не соответствуют поисковому запросу", relevantResults);
Вот и все! Запускаем тест и наслаждаемся результатом!

Полный код можно посмотреть на гитхабе.

Еще почитать по теме:

    Обсудить проект_
    Если у вас есть ИТ-проблема, оставьте ваши контакты, и мы поможем составить план ее решения. Обещаем не слать спам.
    Нажимая, я говорю «Да»
    политике конфиденциальности
    hello@softwarecats.dev
    Новосибирск, ул. Демакова
    23/5, оф.308
    Контакты_

    Выполненные проекты:

      Руководитель отдела тестирования Software Cats