Как писать автотесты на java selenium
Перейти к содержимому

Как писать автотесты на java selenium

  • автор:

Как писать автотесты с Selenium

Как писать автотесты с Selenium

Автоматизируем проверку имени пользователя на Java.

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

Плюс Selenium в том, что он поддерживает самые популярные языки программирования (Java, Python, JavaScript, PHP).

статьи по теме:

Что нужно знать.

Чтобы лучше понять, как работает Selenium, напишем тест на Java.

Сравнение имени пользователя и логина: пишем код

Напишем тест, который будет открывать «Википедию», логиниться и проверять, соответствует ли имя пользователя его логину.

  • 1. Устанавливаем WebDriver— драйвер, который управляет работой браузера (открывает страницы и отправляет им команды). Тест будет написан для Chrome, поэтому понадобится драйвер для последней версии Chrome.
  • 2. Подтягиваем зависимость для Selenium-java в pom.xml Maven-проекта.
  org.seleniumhq.selenium selenium-java 4.0.0  
  • 3. Создаем три класса в папке Test:
    • WikiLoginPage (отвечает за работу со страницей авторизации).
    • WikiMainPage (отвечает за страницу, которая загружается после авторизации).
    • WikiLoginTest (основной тестовый класс).

    Также необходимо выставить небольшую задержку в 5 секунд, чтобы все статические элементы страницы успели загрузиться — timeouts().implicitlyWait(Duration.ofSeconds(5)). Аннотация @BeforeClass говорит о том, что этот метод будет вызван только один раз до запуска всех тестов. Метод quitDriver завершает работу драйвера и закрывает браузер.

    Аннотация @AfterClass обеспечивает его вызов только после того, как отработают все остальные методы. В переменные name и password прописываем данные пользователя, которые будем проверять.

    import org.junit.AfterClass; import org.junit.BeforeClass; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.time.Duration; public class WikiLoginTest < public static WebDriver driver; public static WikiLoginPage wikiLoginPage; public static WikiMainPage wikiMainPage; public static String url = "https://ru.wikipedia.org/w/index.php?title=Служебная:Вход&returnto=Заглавная+страница"; public static String name = "your_name"; public static String password = "your_password"; @BeforeClass public static void openWikiLoginPage() < System.setProperty("webdriver.chrome.driver", "c:/chromedriver.exe"); driver = new ChromeDriver(); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5)); driver.get(url); wikiLoginPage = new WikiLoginPage(driver); wikiMainPage = new WikiMainPage(driver); >@AfterClass public static void quitDriver() < driver.quit(); >>
    • 5. Теперь нужен класс для работы со страницей ввода имени пользователя и пароля — WikiLoginPage. В нем с помощью PageFactory создаем хранилища объектов. К статическим объектам страницы (WebElement) обращаемся с помощью локаторов и аннотации @FindBy. В @FindBy передаем id элемента. Чтобы выбрать идентификатор для элемента, в Google DevTools нажимаем правой кнопкой мыши на элемент, а затем выбираем «посмотреть код» и копируем id.

    • В тесте мы будем использовать три локатора:
      • nameField — для имени пользователя;
      • passwordField — для пароля;
      • loginButton — для кнопки авторизации.
      import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class WikiLoginPage < public WebDriver driver; public WikiLoginPage(WebDriver driver) < PageFactory.initElements(driver, this); this.driver = driver; >@FindBy(id = "wpName1") WebElement nameField; @FindBy(id = "wpPassword1") WebElement passwordField; @FindBy(id = "wpLoginAttempt") WebElement loginButton; public void inputName(String name) < nameField.sendKeys(name); >public void inputPassword(String password) < passwordField.sendKeys(password); >public void clickLoginButton() < loginButton.click(); >>
      • 6. В классе WikiMainPage пишем локатор для определения имени пользователя (userName) и метод (getText) для получения текста из имени. У userName нет своего id, а потому в FindBy передаем xpath. xpath — это язык запросов, с помощью которого можно обращаться к элементам страницы.
      import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class WikiMainPage < public WebDriver driver; public WikiMainPage(WebDriver driver) < PageFactory.initElements(driver, this); this.driver = driver; >@FindBy(xpath = "//*[@id=\"pt-userpage\"]/a/span") private WebElement userName; public String getUserName()
      • 7. Когда оба класса готовы, дорабатываем WikiLoginTest — добавляем импорты для работы теста и пишем тестовый метод.
      import org.junit.Test; import org.junit.Assert;
      • Метод wikiLoginTest проверяет совпадение имени пользователя с отображаемым на странице. Для этого поочередно вызываются все методы, работающие с элементами страницы. После этого сравниваем значение текста элемента (wikiMainPage.getUserName()) с переменной, в которой хранится имя пользователя (name). Аннотация @Test помечает метод как тестовый.
      @Test public void wikiLoginTest()
      • 8. Запускаем тест — в левом нижнем углу отобразится тестовый класс (WikiLoginTest) с удачно запущенным тестовым методом (wikiLoginTest) и временем его работы. Если тесты падают, они становятся красными.

      • Этот автотест можно доработать. Например, вынести все переменные в отдельный конфигурационный файл. Также можно отойти от явного управления драйверами (особенно если будет использован не один браузер). Для этого понадобится библиотека WebDriverManager, которая автоматизирует загрузку драйверов, поиск браузеров в системе, запуск в Docker-контейнерах. С WebDriverManager не придется каждый раз открывать браузер при вызове тестовых методов.

      Готовый код можно найти тут.

      Архитектура высоких нагрузок

      Архитектура автотестов на Java с нуля

      Архитектура автотестов на Java с нуля

      Даниил Шатухин

      Даниил Шатухин Редактор в «Хабре», тестировщик и любитель веба

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

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

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

      Освойте профессию «Java-разработчик»
      Java-разработчик

      Java уже 20 лет в мировом топе языков программирования. На нем создают сложные финансовые сервисы, стриминги и маркетплейсы. Освойте технологии, которые нужны для backend-разработки, за 14 месяцев.

      картинка (93)

      Профессия / 14 месяцев
      Java-разработчик
      Освойте востребованный язык
      3 933 ₽/мес 7 150 ₽/мес

      Group 1321314345 (5)

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

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

      Документация

      • рутинные тесты, которые занимают много времени, часто запускаются и требуют постоянного воспроизведения. Например, в проекте есть анкета для обратной связи с большим количеством полей и входных данных. Ручное заполнение может занимать 5–10 минут, а запуск автоматизированного теста — несколько секунд. Автоматизация позволит освободить время на более приоритетные и интересные задачи;
      • места с заведомо большим количеством багов. На каждом проекте они разные, но к ним, например, может относиться и часто обновляемый код.

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

      Станьте Java-разработчиком
      и создавайте сложные сервисы
      на востребованном языке

      Инструменты

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

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

      Обычно стек инструментов и технологий для автоматизации на Java выглядит так:

      • Selenide — популярный фреймворк для автоматизации тестирования веба на базе Selenium WebDriver;
      • Allure Testops — инструмент для простого создания подробных отчетов. Поддерживает скриншоты, скринкасты и снапшоты состояния страниц во время выполнения теста. Все это позволяет не только увидеть наличие ошибок, но и посмотреть на сами ошибки визуально;

      Отчеты в Allure Testops

      • JUnit — инструмент для модульного тестирования ПО на Java;
      • Rest Assured — библиотека для работы с REST-службами и тестирования API;
      • Jenkins — открытая система для непрерывной интеграции ПО;

      Непрерывная интеграция Jenkins

      • Git — распределенная система управления версиями. Можно использовать любой удобный сервис, к примеру GitHub, GitLab или Bitbucket. При желании можно поднять собственный git-сервер.

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

      В этом случае важно понимать, что делает каждая установленная библиотека. Не надо устанавливать большой и тяжелый модуль из-за пары методов. Также накапливайте опыт, запоминайте, какие инструменты эффективнее, а какие только усложняют архитектуру. Это позволит на новом проекте сразу понять, от каких библиотек можно отказаться.

      Паттерны проектирования

      Автоматизация тестирования — уже сложившаяся сфера со своими правилами и подходами. Для упрощения разработки существует набор паттернов проектирования:

      • Для структурирования кода существует понятие Page Object. Принцип заключается в объединении элементов страниц в свойства класса. Важно, что для каждой страницы создается ровно один класс, который содержит элементы в качестве свойств. В одном модуле мы храним локаторы, а в другом — взаимодействуем с ними. Это помогает повторно использовать локаторы и давать им понятные названия.
      • Для запуска одних и тех же тестов с разными данными обычно используется подход Data Providers. Буквально представьте, что в вашем проекте есть отдельный модуль, поставляющий данные для тестов. Вам не надо самостоятельно генерировать данные, а достаточно просто вызвать ранее написанный модуль. Это упростит работу и поможет сэкономить время, ведь можно будет просто обратиться к «поставщику».
      • Также следует использовать декораторы и дополнительные методы фреймворков, к которым можно отнести аннотации JUnit. Например, с помощью аннотации Issue, Story, CsvSource и Feature можно указать версию тестируемого приложения, кратко описать тестовый сценарии, добавить ссылку на тест в трекинговую систему или указать список тестовых данных.

      Что можно автоматизировать

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

      Мобильные приложения и «железо» обычно тестируют отдельные QA-команды. Связано это с тем, что в тестировании приложений есть свои особенности и сценарии, которые практически не встречаются в веб-приложениях, а для тестирования «железа» необходимы специальные навыки. Фронтенд- и бэкенд-тестировщики обычно работают вместе и часто общаются с разработчиками этих систем.

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

      Цель компании — получать прибыль; добиться ее можно с помощью веб-приложения. Поэтому в первую очередь следует покрывать тестами те части проекта, которые отвечают за продажи и аналитику. К примеру, на сайте есть форма оплаты и обратной связи. В первую очередь стоит обратить внимание на тестирование части, которая отвечает за получение денег. Ведь если никто не сможет купить продукт, то и обратная связь не понадобится.

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

      Советы для разработки автотестов

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

      Общий код стоит выносить

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

      Писать переиспользуемый код

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

      Тесты должны быть удобными

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

      Тесты должны быть простыми

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

      Разделение на модули

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

      Интеграции

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

      Главное кратко

      • Автоматизация тестирования — сложный процесс, требующий времени на внедрение и ресурсов на поддержание. Нельзя написать код один раз и оставить его без присмотра.
      • Автотесты принесут пользу только при грамотном подходе и выборе инструментов. Иначе они просто заберут силы и время.
      • Не надо автоматизировать всё подряд. Важно в первую очередь заняться теми частями проекта, которые имеют наибольшую значимость.
      • Тесты должны быть «человечными». Зеленая галочка в терминале после прогона не даст никакой полезной информации менеджерам и другим участникам команды. Поэтому следует уделить время генерации подробной и понятной отчетности, из которой каждый сможет получить необходимые для себя данные.
      • Код автотестов должен быть простым и понятным. Сложные конструкции и низкоуровневые вставки сделают только хуже.
      • Использование большого количества сторонних библиотек чаще несет больше вреда, чем пользы. Библиотеки тянут за собой зависимости, которые замедляют сборку. Некоторые вещи уже могут быть реализованы в стандартной библиотеке Java.

      Как написать UI-автотесты, если не умеешь программировать?

      Всем привет! В этой статье пойдет речь о том, как написать простые UI-тесты на языке Java. Это будет интересно тем, кто давно хотел попробовать себя в автоматизации или добавить новенького в свой текущий проект.

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

      Основная часть статьи будет посвящена практическому разбору теста и нюансам их написания.

      Собирайте с собой друзей, хорошее настроение и поехали!

      Что такое UI-тесты? Плюсы и минусы.

      UI-тестирование – это тестирование пользовательского интерфейса программы/сайта/приложения и др.

      Звучит легко, а чем такие автотесты полезны?

      1) Такие тесты используются, чтобы автоматизировать рутинные задачи и однотипные действия, например, проверку товаров в каталогах.

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

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

      Какие инструменты нужны?

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

      • DevTools — это инструмент разработчика, он встроен практически во все современные браузеры и включается по кнопке F12. Здесь потребуется вкладка Elements (Элементы).
      • ChroPath – это плагин для браузера, позволяющий быстро сформировать локатор для элемента страницы. Подробнее об это будет написано дальше. Скачать можно по ссылке: ChroPath.
      • IntelliJ IDEA by JetBrains — интегрированная среда разработки программного обеспечения. С помощью нее будут написаны тесты. Бесплатную версию этой программы можно скачать с официального сайта: Community Edition.
      • JDK Java Development Kit — «комплект для разработки на Java». Это, простыми словами, сам язык Java, без которого мы не сможем написать никакой код. Скачать его можно здесь: Сайт с Amazon Corretto. А как установить быстро и понятно можно посмотреть здесь: Как скачать и установить Amazon Corretto. Также кроме Amazon Corretto можно установить другие JDK, вот например: Инструкция.
      • Maven — инструмент для управления и сборки проектов на Java. Он очень облегчает работу с проектами, так что этот пункт не стоит пропускать. Установка Maven.

      Создаем проект и добавляем туда нужные плюшки.

      1. Открываем IntelliJ IDEA.

      2. Нажимаем File – New – Project.

      3. Выбираем тип проекта Maven (на этом моменте убедитесь, что в Project SDK стоит как раз Amazon Corretto).

      4. Нажимаем Next.

      5. В блокe Name задаем название проекта, а в Location папку, где он будет лежать.

      6. Нажимаем Finish. Проект создан.

      Настройка зависимостей

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

      1. Развернуть папку с названием проекта в левом баре.

      1. Открыть файл pom.xml (когда проект только-только создан файл открыт по умолчанию).
        pom.xml — это XML-файл, который содержит информацию о деталях проекта, и конфигурации используемых для создания проекта на Maven.
      2. Добавить в project новые зависимости из списка:

        com.codeborne
        selenide
        5.23.2


      junit
      junit
      4.13.2
      test

    • Затем обязательно нужно нажать кнопку Load Maven Changes, чтобы изменения сохранились.
    • Другие зависимости можно найти и самостоятельно добавить в проект на сайте: https://mvnrepository.com.

      Как работать в IntelliJ IDEA

      Прежде, чем переходить к самой интересной части и начинать писать тест, я предлагаю (настоятельно ! ��) ознакомиться с этим блоком, особенно, если вы еще не работали в IntelliJ IDEA. Иначе дальше будет сложновато сходу разобраться в интерфейсе программы.

      Как создавать классы

      1. В папке main-java создаем package и называем его POM (page object model).

      1. Далее таким же образом создаем класс, только выбираем не package, а Java Class. Назовем класс MainPage.

      Лучше все слова в названиях классов начинать с заглавной буквы.

      3. Таким же образом создаются классы, где будут лежать тесты, только из другой папки.

      Как запускать тесты

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

      1. Запуск теста из интерфейса. Для этого в тестовом классе нажмите кнопку play. Тест запуститься самостоятельно.

      1. Запуск теста с помощью Maven. Для этого в правом блоке меню выберите команду verify и тесты запустятся точно также.

      А еще это можно сделать через командную строку прямо в программе. В нижнем меню откройте вкладку Terminal и введите команду «mvn verify».

      Как отладить тесты.

      1. Внутри теста поставьте брекпоинты (для этого нажмите на строку рядом с нужным фрагментом кода) на моменты теста, которые хотите тщательнее проверить (это может быть нажатие на кнопки, открытие разных страниц, проверки).

      2. Далее нажмите кнопку Debug.

      3. Управляйте шагами теста с помощью меню.

      Структура проекта

      Описание POM и методов

      Обычно проект состоит из нескольких классов package, в котором находятся классы POM (page object model) «объектная модель страницы». Эти классы содержат в себе описание элементов со страниц и методы для взаимодействия с ними.

      //ссылка на package, в котором находится класс package POM;
      //взаимосвязь с нужными библиотеками и фреймворками
      import com.codeborne.selenide.SelenideElement;
      import org.openqa.selenium.support.FindBy;
      import org.openqa.selenium.support.How;
      //взаимосвязь с нужными библиотеками и фреймворками название класса
      public class TestClassPage <
      //описание SelenideElement (элемент со страницы)
      @FindBy(how = How.XPATH (CLASS_NAME, NAME, ID и др) using = «локатор xpath или название класса (другого атрибута) элемента»)
      private SelenideElement elementName;
      //метод для взаимодействия с вышеописанным элементом
      public TestClass testMethodName() <
      elementName.click();
      return this;
      >
      >

      В классах добавляются конструкции для описания SelenideElement. Таким образом элемент описывается как переменная. Благодаря этому с ним удобнее будет взаимодействовать и поменять локатор, если понадобится.

      В How прописываем атрибут элемента, в этом случает это имя класса, а в using значение класса, которые находим в elements. Атрибутом может быть Xpath, Class_NAME, NAME и много других.

      Теперь напишем метод для взаимодействия с элементом. Почему нельзя просто взять элемент и с ним делать всякие вещи в тесте? Можно, но так возможно получить различные ошибки как при написании кода, так при воспроизведении теста, так как не будет соблюдаться принцип инкапсуляции (об этом можно прочитать на досуге ��).

      Чтобы написать метод добавляем в код такую конструкцию.

      public MainPage goToTheEnterAccountButton() enterToAccountButton.click();
      return this;
      >

      Когда написали внутри метода имя переменной с кнопкой «Войти», поставьте рядом с ним точку. Вы увидите все доступные взаимодействия для этого элемента.

      Так как нужно нажать на кнопку, чтобы перейти на страницу авторизации, выберем функцию click.

      Метод готов, теперь его можно будет вызвать в тесте.

      Как еще можно взаимодействовать с элементом.

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

      Подбор атрибута и локатора аналогичен тому, как это делается в SelenideElement.

      $(byText(«Тест элемент»)).shouldBe(Condition.visible).click();
      $(byClassName(«test_element_class»)).shouldBe(Condition.visible).click();
      $(byId(«test_element_id»)).shouldBe(Condition.visible).click();
      $(byName(«element_name»)).shouldBe(Condition.visible).click();

      Описание тестового класса.

      Из чего состоит тестовый класс показано ниже. Эту структуру можно использовать в своих проектах.

      import POM.TestClassPage;
      import org.junit.After;
      import org.junit.Before;
      import org.junit.Test;

      import static com.codeborne.selenide.Selenide.*;
      import static com.codeborne.selenide.Selenide.closeWebDriver;
      import static org.junit.Assert.assertEquals;
      import static org.junit.Assert.assertTrue;

      //название тестового класса
      public class TestClass

      //обращение к классу из POM, чтобы взаимодействовать с его элементами
      private TestClassPage testClassPage;

      //переменные, которые могут быть нужны в тесте
      private final String number = «12121212»;

      //аннотация Before — внутри прописывается то, что нужно сделать ДО теста
      @Before
      public void setUp() //открытие страницы веб-сайта с привязкой его к классу из POM; делается с
      //помощью инструментов Selenide (WebDriver)
      testClassPage = open(«https://testSite.ru/», TestClassPage.class);
      >

      //аннотация After, содержит то, что нужно сделать ПОСЛЕ теста
      @After
      public void tearDown() //эти методы очищают куки и закрывают браузер
      clearBrowserCookies();
      clearBrowserLocalStorage();
      closeWebDriver();
      >

      //аннотация Test, здесь содержится сам тест и проверки
      @Test
      //название теста
      public void testName() //вызов класса из POM, а затем вызов меетода, относящегося к этому классу
      testClassPage.clickToEnterButton();
      //проверка с помощью Assert (бывают разные типы проверок) — здесь проверяется условие
      //на истинность — в скобках указывается условие, которое нужно проверить.
      assertTrue(testClassPage.openAuthPage());
      >
      >

      Начнем писать автотесты

      Первый тест

      Работа в POM

      Чтобы написать первый тест разберем небольшой тест-кейс.

      1. Открываем сайт https://rostov.rt.ru/

      2. Нажимаем на кнопку «Войти».

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

      Что мы видим из этого тест-кейса? За один маленький тест открывается 2 страницы, а также идет взаимодействие с двумя элементами. Это нужно будет описать в коде. Начнем с описания кнопки и заголовка.

      Для этого пойдем по следующему алгоритму:

      1. Создайте package и назовите его POM.

      2. В package создайте класс и назовите его MainPage.

      3. Так как нужно описать кнопку «Войти» идем в DevTools, открываем вкладку Elements. Выберите инструмент для просмотра элементов.

      4. В коде страницы видим следующую конструкцию, которая подсвечивается при наведении на кнопку «Войти»:

      5. Создаем Selenide Element с этим классом.

      @FindBy(how = How.XPATH, using = «sp-l-0-2»)
      private SelenideElement enterToAccountButton;

      6. Создаем метод для взаимодействия с кнопкой «Войти». В реальности мы бы кликнули на нее левой кнопкой мыши. Здесь за такое же действие отвечает функция click().

      public MainPage goToTheEnterAccountButton() enterToAccountButton.click();
      return this;
      >

      Дальше нужно описать вторую страницу, используемую в тесте.

      1. В POM создаем класс AuthPage. Дальше описываем заголовок страницы как SelenideElement.

      2. Написать локатор к титулу можно и с по CLASS_NAME, и по Xpath. На этом этапе советую использовать ChroPath.

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

      @FindBy(how = How.XPATH, using = «//h1[contains(text(),’Авторизация по коду’)]»)
      private SelenideElement authPageTittle;

      4. Теперь напишем метод для проверки текста заголовка.

      Используем ту же конструкцию, что дана в части «Структура проекта». Только тип возвращаемых данных меняем на Boolean. Это нужно потому, что мы будем проверять истинность условия (действительно ли заголовок содержит текст «Авторизация по коду»).

      public boolean openAuthPage() //вызываем переменную с заголовком
      //дальше пишем условие — переменая должна содержать текст и в скобках пишем необходимый текст
      authPageTittle.shouldHave(Condition.exactText(«Авторизация по коду»));
      //если условие указанное выше выполняется, то метод должен вернуть true — правда
      return true;
      >

      Дальше этот метод тоже можно будет использовать в тесте.

      Написание теста

      Тестом считается именно часть кода, написанная внутри метода под аннотацией @Test. Но нужно учитывать и то, что нужно будет сделать до и после теста.

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

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

      1. Создадим тестовый класс EnterTest.

      2. И сразу обращаемся к классам, с которыми будем взаимодействовать.

      private MainPage mainPage;
      private AuthPage authPage;

      3. В этом случае перед тестом нужно открыть главную страницу сайта. Этот этап пойдет в аннотацию Before.

      @Before
      public void setUp() mainPage = open(«https://voronezh.rt.ru/», MainPage.class);
      >

      4. Дальше (уже внутри теста) происходит нажатие на кнопку «Войти». Тест нужно будет назвать. Название должно передавать смысл проверки и содержать слово Test.

      @Test
      public void openAuthorizationTest() mainPage.goToTheEnterAccountButton();
      >

      5. Затем открывается уже другая страница, связанная с классом AuthPage. Ее нужно открыть точно также, как MainPage в начале теста, иначе программа не поймет с какой страницы она должна брать данные.

      6. А затем по тесту мы должны провести проверку – правильный ли на странице заголовок. Последний шаг теста можно добавить сразу же в Assert.

      Первый тест готов. Теперь его можно запускать. При запуске программа сама запустит тест в браузере Google Chrome.

      После успешно пройденного теста вы увидите внизу экрана такое изображение:

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

      Второй тест

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

      POM

      Для этого нужно будет дописать элементы и методы в классе AuthPage.

      1. Бокс для номера телефона или email опишем через Xpath. Но также можно это сделать через How.ID.

      Получается такая переменная:

      @FindBy(how = How.XPATH, using = «//input[@id=’address’]»)
      private SelenideElement setNumberOrEmail;

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

      Для этого в скобках у названия пишем String (тип передаваемых данных, в этому случае – строка) и название переменной.

      public AuthPage setNumberOrEmail(String number)

      Дальше нужно описать действие, имитирующее заполнение бокса. Вызываем переменную setNumberOrEmail и функцию setValue. В скобках функции передаем переменную (их может быть несколько).

      public AuthPage setNumberOrEmail(String number) setNumberOrEmail.setValue(number);
      return this;
      >

      3. Опишем кнопку «Получить код». Описать локатор также можно через Xpath, попробуйте найти его самостоятельно на сайте.

      @FindBy(how = How.XPATH, using = «//button[@id=’otp_get_code’]»)
      private SelenideElement getCodeButton;

      4. Дальше пишем метод, который нажимает на кнопку «Получить код». Он не будет возвращать true или false, не будет содержать переменных. Поэтому этот метод можно сделать по аналогии с тем, что был дан в первом тесте.

      public AuthPage getCode() getCodeButton.click();
      return this;
      >

      5. Опишем переменную с текстом ошибки. Это можно сделать как с помощью CLASS_NAME, так и с Xpath.

      @FindBy(how = How.CLASS_NAME, using = «rt-input-container»)
      private SelenideElement errorText;

      6. Напишем метод с проверкой текста сообщения об ошибке. Он будет аналогичен методу из первого теста.

      public boolean getErrorText() errorText.shouldHave(Condition.exactText(«

      E-mail или мобильный телефон\n» +
      «Введите телефон в формате +7ХХХХХХХХХХ или +375XXXXXXXXX, или email в формате example@email.ru

      «));
      return true;
      >

      Тест

      Этот тест можно будет написать в том же тестовом классе, так как происходит проверка функциональности из одного блока.

      1. В тестовом классе описываем переменную. В ней будет содержаться условный номер телефона.

      private final String number = «12121212»;

      2. Создаем новый тест и называем его по-другому. Нажатие на кнопку «Войти» и открытие страницы авторизации остается также, как и в прошлом тесте.

      3. Чтобы написать номер телефона на странице вызовем 2 метода с authPage. Это можно сделать так:

      А можно таким образом. Этот способ предпочтительнее, так как тест выглядит лаконичнее.

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

      Третий тест

      В третьем тесте нужно будет открыть вкладку «Интернет» на главной странице. Затем из выпадающего меню выберем вкладку «Домашний интернет». После этого совершится переход на новую страницу и там нужно будет выбрать тариф «Облачный». После выбора тарифа будет открыта страница с подробностями о нем и нужно будет убедиться, что открыта правильная страница.

      POM

      1. В классе MainPage описываем кнопку «Интернет» и метод для взаимодействия с ней.

      @FindBy(how = How.XPATH, using = «.//span[contains(text(),’Интернет’)]»)
      private SelenideElement internetButton;

      Метод строится также по стандартному типу.

      public MainPage clickToInternetButton() internetButton.click();
      return this;
      >

      2. Чтобы описать кнопку «Домашний интернет» будем использовать команду Find. Здесь проще всего искать ее по тексту.

      public MainPage clickToHomeInternetButton() $(byText(«Домашний интернет»)).shouldBe(Condition.visible).click();
      return this;
      >

      3. Дальше откроется страница с выбором тарифов. Для нее создадим новый класс. Назовем его HomeInternetPage.

      На странице нужно будет нажать на стрелку, чтобы прокрутить бары с выбором тарифов, а затем нажать на карточку с тарифом «Облачный».

      4. Описать кнопку-стрелку можно с помощью CLASS_NAME.

      @FindBy(how = How.CLASS_NAME, using = «rt-carousel-v3-arrow»)
      private SelenideElement arrowButton;

      5. Чтобы описать нажатие на карточку тарифа будем нажимать на заголовок. Описать его лучше всего через Xpath, так как class name не уникальный в данном случае для разных тарифов.

      @FindBy(how = How.XPATH, using = «//div[contains(text(),’Облачный’)]»)
      private SelenideElement oblachInternetButton;

      6. В этот раз можно объединить действия в общем методе под названием chooseTariff.

      public HomeInternetPage chooseTariff() arrowButton.shouldBe(Condition.visible).click();
      oblachInternetButton.click();
      return this;
      >

      7. Теперь опишем класс для страницы с подробным описанием тарифа. Я заранее называю его CreateOrderPage, так как дальше он будет использоваться еще и в другом тесте.

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

      @FindBy(how = How.XPATH, using = «//h2[contains(text(),’Облачный’)]»)
      private SelenideElement tariffTitle;

      public boolean textFromTitleOrder() tariffTitle.shouldHave(Condition.text(«Облачный»));
      return true;
      >

      Дополнения к тесту

      А еще на этом этапе усложним часть, описанную в @Before.

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

      Для этого в MainPage добавим кнопку:

      @FindBy(how = How.CLASS_NAME, using = «rt-button-small»)
      private SelenideElement continueButton ;

      public MainPage clickToContinueButton() continueButton.click();
      return this;
      >

      Теперь этот метод можно вызывать перед тестом.

      Тест

      1. Создадим тестовый класс InternetTariffTest. В нем сразу нужно будет обратиться к трем страницам.

      private MainPage mainPage;
      private HomeInternetPage homeInternetPage;
      private CreateOrderPage createOrderPage;

      2. В @Before теперь добавляем еще один метод с подтверждением региона.

      @Before
      public void setUp() mainPage = open(«https://voronezh.rt.ru/», MainPage.class);
      mainPage.clickToContinueButton();
      >

      3. В самом тесте сначала вызываем методы с открытием страницы «Домашний интернет».

      @Test
      public void chooseInternetTariffTest() mainPage.clickToInternetButton()
      .clickToHomeInternetButton();

      4. Затем открываем страницу с выбором тарифов и вызываем метод.

      @Test
      public void chooseInternetTariffTest() mainPage.clickToInternetButton()
      .clickToHomeInternetButton();
      homeInternetPage = open(«https://voronezh.rt.ru/homeinternet», HomeInternetPage.class);
      homeInternetPage.chooseTariff();

      5. После этого переходим на страницу с подробной информацией о тарифе и делаем проверку.

      @Test
      public void chooseInternetTariffTest() mainPage.clickToInternetButton()
      .clickToHomeInternetButton();
      homeInternetPage = open(«https://voronezh.rt.ru/homeinternet», HomeInternetPage.class);
      homeInternetPage.chooseTariff();
      createOrderPage = open(«https://voronezh.rt.ru/about_offer?offer=418923262504&cardId» +
      «=3ee2ecc6&lcs=active&pr7 POSTPAIDUNLIM&ref=%2Fhomeinternet&tech 2&speed=100&tech=2&speed=100&tech=2&speed=100&cardPos=5»,
      CreateOrderPage.class);
      assertTrue(createOrderPage.textFromTitleOrder());
      >

      Четвертый тест

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

      POM

      Для оформления заявки нужно заполнить поля с адресом, именем и номером телефона. Потом нажать кнопку отправить. Но если адрес и номер некорректные, то на странице появятся 2 сообщения. Все эти элементы и нужно описать.

      1. В данном случае все боксы для данных удобно описать с помощью атрибута Name.

      @FindBy(how = How.NAME, using = «address»)
      private SelenideElement addressBox;

      @FindBy(how = How.NAME, using = «fullName»)
      private SelenideElement nameBox;

      @FindBy(how = How.NAME, using = «phoneNumber»)
      private SelenideElement numberBox;

      2. Сообщения об ошибке можно описать по Xpath, а можно найти в методе с помощью find.

      @FindBy(how = How.XPATH, using = «//span[contains(text(),’Выберите дом из справочника’)]»)
      private SelenideElement errorAddress;

      @FindBy(how = How.XPATH, using = «//span[contains(text(),’Введите существующий номер телефона’)]»)
      private SelenideElement errorPhone;

      3. Чтобы заполнить заявку можно сделать метод, который будет получать 3 переменные String и заполнять соответствующие поля.

      public CreateOrderPage fillOrder(String address, String name, String phoneNumber) addressBox.setValue(address);
      nameBox.setValue(name);
      numberBox.setValue(phoneNumber);
      return this;
      >

      4. А далее нужно написать метод, который будет проверять, что сообщения об ошибках отображаются на странице. В предыдущих методах мы проверяли, содержит ли элемент текст. Теперь будет проверяться то, существует ли элемент на странице.

      public boolean errorMessagesIsVisible() errorAddress.shouldBe(Condition.visible);
      errorPhone.shouldBe(Condition.visible);
      return true;
      >

      Тест

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

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

      private MainPage mainPage;
      private HomeInternetPage homeInternetPage;
      private CreateOrderPage createOrderPage;

      2. Дальше нужно создать переменные.

      private final String address = «г Воронеж, ул Минская, д 100000»;
      private final String name = «Иванов Иван Иваныч»;
      private final String phone = «7900000000» ;

      3. В @Before прописывается полный путь вплоть до открытия страницы с подробностями о тарифе.

      @Before
      public void setUp()

      mainPage = open(«https://voronezh.rt.ru/», MainPage.class);
      mainPage.clickToInternetButton()
      .clickToHomeInternetButton();
      homeInternetPage = open(«https://voronezh.rt.ru/homeinternet», HomeInternetPage.class);
      homeInternetPage.chooseTariff();
      createOrderPage = open(«https://voronezh.rt.ru/about_offer?offer=418923262504&cardId=3ee2ecc6&lcs=active&pr7 POSTPAIDUNLIM&ref=%2Fhomeinternet&tech 2&speed=100&tech=2&speed=100&tech=2&speed=100&cardPos=5», CreateOrderPage.class);
      >

      4. А сам тест выглядит очень лаконично. Вызывается страница с созданием заявки, а потом идет проверка.

      @Test
      public void creatingInternetOrderWithoutFieldsTest() createOrderPage.fillOrder(address, name, phone);
      assertTrue(createOrderPage.errorMessagesIsVisible());
      >

      Подведем итоги

      Теперь вы умеете писать самые простые UI-тесты на Java с помощью фреймворка Selenide. Возможности автоматизированного тестирования только начинаются на этом этапе. Существуют юнит-тесты, API-тесты, которые могут выполнять другие задачи тестирования.

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

      Файл с тестами, которые разобраны здесь будет приложен к статье. Можно попробовать на их основе сделать своей проект. А также внутри содержится еще один бонусный тест, его тоже можно разобрать самостоятельно в качестве маленького челленджа.

      Всем удачи и спасибо за внимание!

      Пишем автотест с использованием Selenium Webdriver, Java 8 и паттерна Page Object

      В этой статье рассматривается создание достаточного простого автотеста. Статья будет полезна начинающим автоматизаторам.

      Материал изложен максимально доступно, однако, будет значительно проще понять о чем здесь идет речь, если Вы будете иметь хотя бы минимальные представления о языке Java: классы, методы, etc.

      • установленная среда разработки Intellij IDEA (является самой популярной IDE, для большинства случаев достаточно бесплатной версии Community Edition);
      • установленные Java (jdk/openjdk) и Maven, прописанные в системные окружения ОС;
      • браузер Chrome и chromedriver — программа для передачи команд браузеру.

      Создание проекта

      Запустим Intellij IDEA, пройдем первые несколько пунктов, касающихся отправки статистики, импорта проектов, выбора цветовой схемы и т.д. — просто выберем параметры по умолчанию.

      В появившемся в конце окне выберем пункт «Create New Project», а в нем тип проекта Maven. Окно будет иметь вид:

      image

      • Maven — это инструмент сборки Java проектов;
      • Project SDK — версия Java, которая установлена на компьютере;
      • Create from archetype — это возможность создавать проект с определенным архетипом (на данном этапе данный чекбокс отмечать не нужно).

      Нажмем «Next». Откроется следующее окно:

      image

      Groupid и Artifactid — идентификаторы проекта в Maven. Существуют определенные правила заполнения этих пунктов:

      • Groupid — название организации или подразделения занимающихся разработкой проекта. В этом пункте действует тоже правило как и в именовании пакетов Java: доменное имя организации записанное задом наперед. Если у Вас нет своего доменного имени, то можно использовать свой э-мейл, например com.email.email;
      • Artifactid — название проекта;
      • Version — версия проекта.

      Нажмем «Finish»: IDE автоматически откроет файл pom.xml:

      image

      В нем уже появилась информация о проекте, внесенная на предыдущем шаге: Groupid, Artefiactid, Version. Pom.xml — это файл который описывает проект. Pom-файл хранит список всех библиотек (зависимостей), которые используются в проекте.

      Для этого автотеста необходимо добавить две библиотеки: Selenium Java и Junit. Перейдем на центральный репозиторий Maven mvnrepository.com, вобьем в строку поиска Selenium Java и зайдем в раздел библиотеки:

      image

      Выберем нужную версию (в примере будет использована версия 3.14.0). Откроется страница:

      image

      Копируем содержимое блока «Maven» и вставим в файл pom.xml в блок

      Таким образом библиотека будет включена в проект и ее можно будет использовать. Аналогично сделаем с библиотекой Junit (будем использовать версию 4.12).

      image

      Создание пакета и класса

      Раскроем структуру проекта. Директория src содержит в себе две директории: «main» и «test». Для тестов используется, соответственно, директория «test». Откроем директорию «test», кликом правой клавиши мыши по директории «java» выберем пункт «New», а затем пункт «Package». В открывшемся диалоговом окне необходимо ввести название пакета. Имя базового пакета должно носить тоже имя, что и Groupid — «org.example».

      Следующий шаг — создание класса Java, в котором пишется код автотеста. Кликом правой клавиши мыши по названию пакета выберем пункт «New», а затем пункт «Java Class».

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

      image

      Настройка IDE

      Прежде чем начать, необходимо настроить IDE. Кликом правой клавиши мыши по названию проекта выберем пункт «Open Module Settings». В открывшемся окне во вкладке «Sources» поле «Language level» по умолчанию имеет значение 5. Необходимо изменить значение поля на 8 (для использования всех возможностей, присутствующих в этой версии Java) и сохранить изменения:

      image

      Далее необходимо изменить версию компилятора Java: нажмем меню «File», а затем выберем пункт Settings.

      В открывшемся перейдем «Build, Execution, Deployment» -> «Compiler» -> «Java Compiler». По умолчанию установлена версия 1.5. Изменим версию на 8 и сохраним изменения:

      image

      Test Suite

      1. Пользователь открывает страницу аутентификации;
      2. Пользователь производит ввод валидных логина и пароля;
      3. Пользователь удостоверяется в успешной аутентификации — об этом свидетельствует имя пользователя в верхнем правом углу окна;
      4. Пользователь осуществляет выход из аккаунта путем нажатия на имя пользователя в верхнем правом углу окна с последующим нажатием на кнопку «Выйти…».

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

      Для примера будет использоваться аккаунт Яндекс (учетная запись заранее создана вручную).

      Первый метод

      В классе LoginTest будет описана логика теста. Создадим в этом классе метод «setup()», в котором будут описаны предварительные настройки. Итак, для запуска браузера необходимо создать объект драйвера:

      WebDriver driver = new ChromeDriver();

      Перед созданием объекта WebDriver следует установить зависимость, определяющую путь к chomedriver (в ОС семейства Windows дополнительно необходимо указывать расширение .exe):

      System.setProperty("webdriver.chrome.driver", "/usr/bin/chromedriver");

      Чтобы ход теста отображался в полностью открытом окне, необходимо сказать об этом драйверу:

      driver.manage().window().maximaze();

      Случается, что элементы на страницах доступны не сразу, и необходимо дождаться появления элемента. Для этого существуют ожидания. Они бывают двух видов: явные и неявные. В примере будет использовано неявное ожидание Implicitly Wait, которое задается вначале теста и будет работать при каждом вызове метода поиска элемента:

      driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

      Таким образом, если элемент не найден, то драйвер будет ждать его появления в течении заданного времени (10 секунд) и шагом в 500 мс. Как только элемент будет найден, драйвер продолжит работу, однако, в противном случае тест упадем по истечению времени.

      Для передачи драйверу адреса страницы используется команда:

      driver.get("https://passport.yandex.ru/auth")

      Выносим настройки

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

      Создадим в каталоге «test» еще один каталог с названием «resources», а в нем обычный файл «conf.properties», в который поместим переменную:

      loginpage = https://passport.yandex.ru/auth

      а также внесем сюда путь до драйвера

      chromedriver = /usr/bin/chromedriver

      image

      В пакете «org.example» создадим еще один класс «ConfProperties», который будет читать записанные в файл «conf.properties» значения:

      image

      package org.example; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; public class ConfProperties < protected static FileInputStream fileInputStream; protected static Properties PROPERTIES; static < try < //указание пути до файла с настройками fileInputStream = new FileInputStream("src/test/resources/conf.properties"); PROPERTIES = new Properties(); PROPERTIES.load(fileInputStream); >catch (IOException e) < e.printStackTrace(); //обработка возможного исключения (нет файла и т.п.) >finally < if (fileInputStream != null) try < fileInputStream.close(); >catch (IOException e) < e.printStackTrace(); >> > /** * метод для возврата строки со значением из файла с настройками */ public static String getProperty(String key) < return PROPERTIES.getProperty(key); >>

      Обзор первого метода

      image

      Метод «setup()» пометим аннотацией Junit «@BeforeClass», которая указывает на то, что метод будет выполняться один раз до выполнения всех тестов в классе. Тестовые методы в Junit помечаются аннотацией Test.

      package org.example; import org.junit.BeforeClass; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.util.concurrent.TimeUnit; public class LoginTest < /** * осуществление первоначальной настройки */ @BeforeClass public static void setup() < //определение пути до драйвера и его настройка System.setProperty("webdriver.chrome.driver", ConfProperties.getProperty("chromedriver")); //создание экземпляра драйвера WebDriver driver = new ChromeDriver(); //окно разворачивается на полный экран driver.manage().window().maximize(); //задержка на выполнение теста = 10 сек. driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //получение ссылки на страницу входа из файла настроек driver.get(ConfProperties.getProperty("loginpage")); >>

      Page Object

      При использовании Page Object элементы страниц, а также методы непосредственного взаимодействия с ними, выносятся в отдельный класс.

      Создадим в пакете «org.example» класс LoginPage, который будет содержать локацию элементов страницы логина и методы для взаимодействия с этими элементами.

      Откроем страницу авторизации в сервисах Яндекс (https://passport.yandex.ru/auth) в браузере Chrome. Для определения локаторов элементов страницы, с которыми будет взаимодействовать автотест, воспользуемся инструментами разработчика. Кликом правой кнопки мыши вызовем меню «Просмотреть код». В появившейся панели нажмем на значок курсора (левый верхний угол панели разработчика) и наведем курсор на интересующий нас элемент — поле ввода логина.

      В результате мы увидим этот элемент среди множества других. Теперь мы можем скопировать его локацию. Для этого кликаем правой кнопкой мыши по выделенному в панели разработчика элементу, выбираем меню «Copy» -> «Copy XPath».

      //*[@id="root"]/div/div/div[2]/div/div/div[3]/div[2]/div/div/div[1]/form/div[1]/div[1]/label

      Для локации элементов в Page Object используется аннотация @FindBy.

      Напишем следующий код:

      @FindBy(xpath = "//*[@id="root"]/div/div/div[2]/div/div/div[3]/div[2]/div/div/div[1]/form/div[1]/div[1]/label") private WebElement loginField;

      Таким образом мы нашли элемент на страницу и назвали его loginField (элемент доступен только внутри класса LoginPage, т.к. является приватным).

      Однако, такой длинный и страшный xpath использовать не рекомендуется (рекомендую к прочтению статью «Не так страшен xpath как его незнание». Если присмотреться, то можно увидеть, что поле ввода логина имеет уникальный id:

      image

      Воспользуемся этим и изменим поиск элемента по xpath:

      @FindBy(xpath = "//*[contains(@id, 'passp-field-login')]")

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

      Аналогично изучим следующие элементы и получим их локаторы.

      @FindBy(xpath = "//*[contains(text(), 'Войти')]") private WebElement loginBtn;

      Поле ввода пароля:

      @FindBy(xpath = "//*[contains(@id, 'passp-field-passwd')]") private WebElement passwdField;

      А теперь напишем методы для взаимодействия с элементами.

      Метод ввода логина:

      public void inputLogin(String login)

      Метод ввода пароля:

      public void inputPasswd(String passwd)

      Метод нажатия кнопки входа:

      public void clickLoginBtn()

      Для того, чтобы аннотация @FindBy заработала, необходимо использовать класс PageFactory. Для этого создадим конструктор и передадим ему в качестве параметра объект Webdriver:

      public WebDriver driver; public LoginPage(WebDriver driver)

      image

      package org.example; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class LoginPage < /** * конструктор класса, занимающийся инициализацией полей класса */ public WebDriver driver; public LoginPage(WebDriver driver) < PageFactory.initElements(driver, this); this.driver = driver; >/** * определение локатора поля ввода логина */ @FindBy(xpath = "//*[contains(@id, 'passp-field-login')]") private WebElement loginField; /** * определение локатора кнопки входа в аккаунт */ @FindBy(xpath = "//*[contains(text(), 'Войти')]/..") private WebElement loginBtn; /** * определение локатора поля ввода пароля */ @FindBy(xpath = "//*[contains(@id, 'passp-field-passwd')]") private WebElement passwdField; /** * метод для ввода логина */ public void inputLogin(String login) < loginField.sendKeys(login); >/** * метод для ввода пароля */ public void inputPasswd(String passwd) < passwdField.sendKeys(passwd); >/** * метод для осуществления нажатия кнопки входа в аккаунт */ public void clickLoginBtn() < loginBtn.click(); >>

      После авторизации мы попадаем на страницу пользователя. Т.к. это уже другая страница, в соответствии с идеологией Page Object нам понадобится отдельный класс для ее описания. Создадим класс ProfilePage, в котором определим локаторы для имени пользователя (как показателя успешного входа в учетную запись), а также кнопки выхода из аккаунта. Помимо этого, напишем методы, которые будут получать имя пользователя и нажимать на кнопку выхода.

      Итого, страница будет иметь следующий вид:

      image

      package org.example; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class ProfilePage < /** * конструктор класса, занимающийся инициализацией полей класса */ public WebDriver driver; public ProfilePage(WebDriver driver) < PageFactory.initElements(driver, this); this.driver = driver; >/** * определение локатора меню пользователя */ @FindBy(xpath = "//*[contains(@class, 'account__name_hasAccentLetter')]") private WebElement userMenu; /** * определение локатора кнопки выхода из аккаунта */ @FindBy(xpath = "//*[contains(@class, 'menu-item_action_exit menu__item menu__item_type_link')]") private WebElement logoutBtn; /** * метод для получения имени пользователя из меню пользователя */ public String getUserName() < String userName = userMenu.getText(); return userName; >/** * метод для нажатия кнопки меню пользователя */ public void entryMenu() < userMenu.click(); >/** * метод для нажатия кнопки выхода из аккаунта */ public void userLogout() < logoutBtn.click(); >>

      Интересный момент: в метод getUserName() пришлось добавить еще одно ожидание, т.к. страница «тяжелая» и загружалась довольно медленно. В итоге тест падал, потому что метод не мог получить имя пользователя. Метод getUserName() с ожиданием:

      public String getUserName() < WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(@class, 'account__name_hasAccentLetter')]"))); String userName = userMenu.getText(); return userName; >

      Вернемся к классу LoginTest и добавим в него созданные ранее классы-страницы путем объявления статических переменных с соответствующими именами:

      public static LoginPage loginPage; public static ProfilePage profilePage;

      Сюда же вынесем переменную для драйвера

      public static WebDriver driver;

      В аннотации @BeforeClass создаем экземпляры классов созданных ранее страниц и присвоим ссылки на них. Создание экземпляра происходит с помощью оператора new. В качестве параметра указываем созданный перед этим объект driver, который передается конструкторам класса, созданным ранее:

      loginPage = new LoginPage(driver); profilePage = new ProfilePage(driver);

      А создание экземпляра драйвера приведем к следующему виду (т.к. он объявлен в качестве переменной):

      driver = new ChromeDriver();

      Тест

      Теперь можно перейти непосредственно к написанию логики теста. Создадим метод loginTest() и пометим его соответствующей аннотацией:

      @Test public void loginTest() < //значение login/password берутся из файла настроек по аналогии с chromedriver //и loginpage //вводим логин loginPage.inputLogin(ConfProperties.getProperty("login")); //нажимаем кнопку входа loginPage.clickLoginBtn(); //вводим пароль loginPage.inputPasswd(ConfProperties.getProperty("password")); //нажимаем кнопку входа loginPage.clickLoginBtn(); //получаем отображаемый логин String user = profilePage.getUserName(); //и сравниваем его с логином из файла настроек Assert.assertEquals(ConfProperties.getProperty("login"), user); >

      Осталось лишь корректно все завершить. Создадим финальный метод и пометим его аннотацией @AfterClass (методы помеченные этой аннотацией выполняются один раз, после завершения всех тестовых методов класса).

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

      @AfterClass public static void tearDown()

      Последняя строка нужна для закрытия окна браузера.

      Обзор теста

      package org.example; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.util.concurrent.TimeUnit; public class LoginTest < public static LoginPage loginPage; public static ProfilePage profilePage; public static WebDriver driver; /** * осуществление первоначальной настройки */ @BeforeClass public static void setup() < //определение пути до драйвера и его настройка System.setProperty("webdriver.chrome.driver", ConfProperties.getProperty("chromedriver")); //создание экземпляра драйвера driver = new ChromeDriver(); loginPage = new LoginPage(driver); profilePage = new ProfilePage(driver); //окно разворачивается на полный экран driver.manage().window().maximize(); //задержка на выполнение теста = 10 сек. driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //получение ссылки на страницу входа из файла настроек driver.get(ConfProperties.getProperty("loginpage")); >/** * тестовый метод для осуществления аутентификации */ @Test public void loginTest() < //получение доступа к методам класса LoginPage для взаимодействия с элементами страницы //значение login/password берутся из файла настроек по аналогии с chromedriver //и loginpage //вводим логин loginPage.inputLogin(ConfProperties.getProperty("login")); //нажимаем кнопку входа loginPage.clickLoginBtn(); //вводим пароль loginPage.inputPasswd(ConfProperties.getProperty("password")); //нажимаем кнопку входа loginPage.clickLoginBtn(); //получаем отображаемый логин String user = profilePage.getUserName(); //и сравниваем его с логином из файла настроек Assert.assertEquals(ConfProperties.getProperty("login"), user); >/** * осуществление выхода из аккаунта с последующим закрытием окна браузера */ @AfterClass public static void tearDown() < profilePage.entryMenu(); profilePage.userLogout(); driver.quit(); >>

      Запуск автотеста

      Для запуска автотестов в Intellij Idea имеется несколько способов:

      • Alt+Shift+F10;
      • Клик правой клавишей мышки по имени тестового класса, после чего в открывшемся меню выбрать Run;

      В результате выполнения автотеста, в консоли Idea я вижу, что тестовый метод loginTest() пройден успешно:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *