selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

22 практических совета по тестированию автоматизации с Selenium WebDriver

Автоматизация тестирования с помощью Selenium позволила тестировщикам веб-сайтов по всему миру легко выполнять автоматическое тестирование веб-сайтов. Webdriver является ключевым компонентом платформы Selenium, с помощью которого вы можете выполнять автоматическое перекрестное браузерное тестирование вашего веб-сайта или веб-приложения на различных типах браузеров, например, Google Chrome, Mozilla Firefox, Safari, Opera, Internet Explorer, Microsoft Edge и т. Д.

В этой статье я поделюсь с вами некоторыми ключевыми советами по автоматизации тестирования Selenium, которые касаются аспектов оптимизации кода, повышения производительности, динамической загрузки веб-страниц, обработки кода CSS и HTML и т. Д.

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

Selenium Совет № 1 — Установка исполняемого пути веб-драйвера Selenium

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

Источник

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

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

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

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

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

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

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

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

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

Настройка IDE

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

Test Suite

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

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

Первый метод

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

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

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

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

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

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

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

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

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

Page Object

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

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

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

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

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

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

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

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

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

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

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

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

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

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

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

selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Смотреть картинку selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Картинка про selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста. Фото selenium webdriver позволяет записать ручные действия пользователя и превратить их в код автотеста

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

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

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

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

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

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

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

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

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

Обзор теста

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

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

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

Источник

Автоматизация тестирования веб-приложения с использованием Selenium WebDriver, Python, и Behave

Перед началом

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

1. Установка нужностей

Как лаконично подсказывает wiki:
Selenium — это инструмент для тестирования Web-приложений.

Так же про него много писали на Хабре:
тут, и тут даже есть частичный перевод не официальной документации

Теперь установим behave. Можно с использованием pip:
pip install behave

А можно скачать тут: behave на pypi
Что такое behave? Behave — это фрейморк для программирования через поведения в python-стиле(Что такое Behavior-driven development?).
Behave использует тесты написанные на натуральном языке, с логикой на python.
Он обладает несколькими серьезными плюсами:

+ Легкая установка
+ Отчеты в формате junit
+ Тесты может писать любой человек на естественном языке.
+ Есть возможность интеграции с jenkins (с другими CI, наверное, тоже)

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

2. Настройка

Опционально можно добавить в директорию содержащую папку steps файл — environment.py c кодом который надо будет выполнять прежде или после определенных событий в тесте.
Подробное описание этого файла тут.
Наш пример будет максимально простым, поэтому мы не будем включать этот файл.

Итого, как выглядит наша директория в минимальной комплектации:

features/
features/everything.feature
features/steps/
features/steps/steps.py

пример из behave tutorial
Вот и вся настройка, можно писать первый тест!

3. Написание и запуск первого теста

Итак, скопируйте код ниже в файл firs_test.py.

Если лень смотреть код, то логика такая:
1. Открыть ya.ru
2. Клацнуть на кнопку «Найти»
3. Проверить, что на странице выдачи есть текст: «Задан пустой поисковый запрос»

Шаги из теста, по декораторам свяжутся с python функциями. (Декораторы обозначены знаком @)

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

Если все прошло хорошо, то отчет будет, примерно, таким:

Заключение

Здесь я привел только самое основное.
Фичи selenium неисчислимы, да и behave много чего умеет. В том числе, отчеты в формате junit и интеграцию с jenkis.
Спасибо за внимание, и хороших выходных!

Список использованных материалов

UPD: Если что-то в статье не очень хорошо написано, или чего-то не хватает, то можно высказаться в комментариях, или написать в личку мне, и мы вместе улучшим ее.

Источник

Selenium 2.0 — WebDriver. Впечатления, проблемы и советы по использованию

Введение

Последние три месяца мне пришлось работать с Selenium 2.0 (WebDriver).
В данной статье я опишу свои впечатления, мысли и опыт, который я приобрел.
Так же я опишу основные действия, которые чаще всего вызывают проблемы и покажу наиболее удачные решения, которые я смог реализовать для них. Возможно есть более правильные подходы — буду рад если оставите их в комментариях.

Коротко о Selenium

Библиотека Selenium позволяет производить тестирование графических web интерфейсов. Ее принцип — максимально точно симулировать деятельность пользователя. По сути — это написание бота, который бегает по страничкам сайта, производит действия и проверяет ожидаемый результат. Selenium 2.0 реализует сообщения с браузерами посредством специальных драйверов. В отличие от Selenium 1.0 он не использует JavaScript, а сообщается напрямую с API браузеров.

Что у меня получилось реализовать

Получилось написать тесты на основе JUnit и Selenium 2.0, объединенные в одно приложение. Данное приложение может выполняться на Selenium Grid — это сеть, во главе с Selenium Hub, который принимает и распределяет поступившие задачи тестирования по своим Selenium Nodes. На различных Selenium Nodes могут быть настроены любые требуемые браузеры. Используемые драйвера — родные драйвера для каждого браузера.

Часть первая. Впечатления

Разное поведение в разных браузерах

Под браузерами я понимаю основные: Firefox, Google Chrome, Opera, Safari, IE8, IE9
Чтобы один и тот же код срабатывал одинаково успешно в разных браузерах, нужно потратить огромное количество времени. Порой нужна железная воля, чтобы не бросить это гиблое дело. В этом плане самые послушные браузеры — Firefox и Google Chrome. По моему личному опыту — жизненно необходимо, чтобы тест мог менять поведение в нужных местах в зависимости от того, какой браузер в данный момент используется. Т.е. он должен иметь информацию о среде, в которой он проходит.

Совет:
Старайся не использовать в тестах объект webDriver напрямую! Создай методы-обертки вокруг основных необходимых тебе методов. Проще менять поведение в одном месте, чем повсеместно в коде всех тестов.

Selenium 2.0 — сырой продукт

Читая множество постов на Stackoverflow в поисках best practices или просто решения проблемы, постоянно натыкаешься на workaround’ы. Причин несколько: различия в работе драйверов браузеров, не выполнение драйверами контракта требуемого функционала, наличие ошибок в версиях, наличие прямой зависимости версии браузера от версии драйвера. Порой он способен просто ронять тест на голом месте (с точки зрения пользователя API) — элемент есть, но он его не видит. По моему опыту много плавающих ошибок, которые намеренно воспроизводятся только через раз при абсолютно схожих условиях и действиях. С Firefox вообще иногда начинается лихорадка и браузер может просто закрыться с примерно таким сообщением: Error communicating with the remote browser. It may have died. Крайне тяжело найти причину, если она вообще доступна пользователю Selenium. По этому порой ситуация беспомощная — просто не работает функционал.

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

Тесты Selenium — зависимые тесты

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

Совет:
Если есть возможность воспроизводить условия теста независимо, т.е. есть прямой доступ к тестируемому приложению и нет преград для разворачивания исходных тестовых данных — вам повезло, изолируйте свои тесты подобным образом — подготавливая данные до теста и очищая их после. К примеру, в восстановлении данных в БД может помочь инструмент Liquibase.
Скорей всего такой возможности нет. В этом случае выход один — помимо самих тестируемых действий, описывать с помощью Selenium так же и действия по их «откатке». Т.е. если пользователь удалил сущность — в конце теста ее необходимо заново создать или загрузить.
Это грешный путь. Так как подобные действия тоже уязвимы и тоже могут оборваться ошибкой, не выполнив своего предназначения.

Тесты Selenium — медленные тесты

Нужно быть готовым, что последовательный прогон большого набора тестов для всех браузеров может занимать большое количество времени, измеряемое в часах (от 30 минут — до 2-3 часов). Это делает все что я описал выше трагедиями и порой похоже на издевательство. Причина в том, что тесты сильно насыщены различными ожиданиями, поиском элементов и прочими медленными действиями.

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

Selenium IDE — не помощник

Selenium IDE — специальный плагин для Firefox, который способен записать все выполняемые действия пользователя в виде скриптов. Там же есть возможность экспорта составленных скриптов в различные языки и в два формата: Selenium 1.0 (RC) и Selenium 2.0 (WebDriver).
В большинстве случаев бесполезная вещь.

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

Совет:
Поиграйтесь с IDE, поймите суть Selenium, можете даже пописать тесты с ее помощью. Но как только почувствуете, что пользы меньше, чем затрат — начинайте делать собственные заготовки. Аккумулируйте их в общем абстрактном классе-предке или в утилитном классе. Начиная с определенного момента ваши тесты могут превратиться просто в перечисление таких методов, разбавленные проверками результата и текущего состояния.

Часть вторая. Практические решения возникающих проблем (Java)

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

Получение элемента (findElement)

Проблема:
WebDriver предоставляет механизм для поиска и получения сущности WebElement:

Теоретически, на поведение этого метода влияет параметр ‘implicit wait’ который можно указать при построении самого webdriver. К примеру, так:

Опять таки, теоретически, это должно явно заставлять webdriver искать элемент в течении указанного времени и ждать либо пока не появится искомый элемент, либо пока не закончится указанный таймаут. Кстати, данный таймаут судя по всему можно выставлять только единожды.
На практике, происходит нечто странное. Пауза выдерживается, но есть внутреннее ощущение, что поиск если и идет по DOM модели, то обновления этой DOM модели не происходит. Для некоторых браузеров получается другая ситуация — элемент уже есть в DOM модели, но еще не отрисовался или отрисовался частично (Google Chrome). WebDriver возвращает найденный наполовину отрисованный элемент и событие click попадает в еще неотрисованные координаты. Метод isDisplayed() в таких случаях не помогает. В любом случае, итог у меня всегда один — элемент визуально уже гарантированно появился, а webDriver его по-прежнему не обнаруживает.

Решение:
Делать грубую паузу. Для того, чтобы не умножать количество строк кода вдвое, рекомендую сделать собственную реализацию метода findElement();
Как я писал выше — для более эффективной работы — тест должен знать какой браузер в данный момент запущен. Для Firefox по моим наблюдениям такой задержки не требуется.
Так же можно воспользоваться инструментом WebDriverWait. Описывать здесь такой вариант не буду, так как я решил остановиться на спячке потока, мне этого достаточно — поэтому проверенного варианта нет. Но там все довольно просто.
В дальнейшем использовать во всех тестах только этот метод и не использовать webDriver.findElement() напрямую.

Получение элементов (findElements)

Проблема и решение аналогичны поиску одного элемента.

Проверка на существование элемента

Если необходимо проверить, что элемент отсутствует — рекомендуется использовать конструкцию:

Вот рекомендация из JavaDocs:

findElement should not be used to look for non-present elements, use findElements(By) and assert zero length response instead.

Скачивание картинки или файла

Проблема:
Есть желание протестировать скачивание файла, что скачанный файл соответствует ожидаемому, а если это картинка — она действительно доступна по указанной ссылке.

Рассуждения:
В 99% случаев вам это не нужно. Еще раз задайтесь вопросом, что вы хотите протестировать? Я практически уверен, что вам достаточно знать, что загрузка доступна. Что ссылка активна, кнопка загрузки enabled и статус ответа после начала скачки равен 200. У вас нет задачи тестировать браузер и его процесс скачивания.
Так же, если тесты проходят на Selenium Grid — то у вас не получится скачать файл и проверить после этого его местонахождение. Файл скачается на Selenium Node, а проверять вы его будете на Selenium Hub. Это разные хосты, по крайней мере в обычной практике.

Решение:
Решение заключается в том, чтобы выполнить обыкновенный HTTP запрос по ссылке ведущей к файлу на сервере, либо по ссылке, по которой сервер должен вернуть такой файл. Если статус полученного от сервера ответа 200 — ссылка верная, файл существует. Все остальные варианты я рассматриваю как недоступность скачивания файла. Так как зачастую запросы должны иметь при себе авторизованные cookies — такие cookies необходимо импортировать из webDriver.
Если одного статуса недостаточно, ничто не мешает вам считать весь InputStream из HttpEntity и далее сравнить его содержимое с эталонным, будь то MD5 сумма или какой-нибудь другой способ.

Очистка значения поля input

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

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

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

Решение:
Есть несколько основных способов.
Первый способ — моделировать действие «выделить все» и сразу после этого выслать новое значение:

Но данное решение у меня работает не на всех браузерах и не всегда.

Второй способ — выслать количество символов backspace, равное длине старого значения. Данное решение некрасиво, но оно эффективно и работает гарантированно во всех браузерах.
Ниже я публикую вариант, которым пользуюсь сам. В нем есть отдельное рассмотрение ситуации, когда браузер — IE, а input с типом file.
Это особенная ситуация. При выполнении команды sendKeys к такому элементу IE заменит старое значение, новым, а не допишет его в конец. Поэтому делать очистку такого поля смысла нет. Более того, подобная попытка приведет к ошибке. Либо по причине несуществующего файла (так как будет попытка найти файл по пустому пути), либо по причине попытки найти файл по пути, строковое значение которого будет равно символу backspace.

Загрузка файла на сервер

Проблема:
Необходимо загрузить файл на сервер, используя стандартные элементы HTML:

Решение:
Я рекомендую просто взять и вынести себе это в отдельный универсальный метод и использовать его каждый раз когда нужно что-либо загрузить через такую форму.

Исключение:
Safari Driver полностью не поддерживает загрузку файла, т.к. насколько я понял, он javascript-based. Появляющееся окно с выбором файла ставит его в тупиковое положение. Такие сценарии нужно либо избегать, либо добиваться результата другим способом — создавать собственный HTTP запрос или подкладывать данные напрямую на стороне сервера, если такая возможность имеется.

Действия с элементами внутри iframe

Проблема:
Если требуемый элемент находится внутри iframe — он не доступен из дефолтного контекста. Вы не сможете обнаружить его в DOM модели и webDriver будет бросать исключение NoSuchElementException.

Решение:
Перед тем как взаимодействовать с этим элементом, необходимо переключить webDriver на контекст iframe элемента. Как я понимаю, это связано с тем, что контекст страницы и контекст iframe на этой странице — это две разных DOM модели.

IE8. Проблема с XPath

Проблема:
IE8, в свойственной ему эксцентричной манере, бывает неверно интерпретирует указатели элементов (By.id, By.xpath и другие).
У меня возникали ситуации когда он игнорировал уточнение для искомого элемента указывающее на его атрибут class.
К примеру IEDriver отказывался различать два разных элемента, найденных по таким локаторам и выводил элементы подходящие обоим вариантам:

Понять в каких ситуациях у него возникают проблемы мне не удалось.
Абсолютно идентичная ситуация происходила с прямым указанием id элемента. WebDriver делает вид что его не существует.

Решение:
Если у IEDriver возникает галлюциногенное заблуждение в поиске элемента (но не у остальных драйверов и браузеров) — лучший выход — изменить XPath. Благо возможных вариантов благодаря гибкости XPath всегда много.

IE8. элемент недоступен для нажатия

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

Решение:
Необходимо выполнить прокрутку. Единственный найденный мной и работающий способ — воспользоваться помощью javascript. На самом деле, WebDriver имеет специальный механизм, призванный помочь с прокруткой до требуемого элемента:

Но он не сработает в случае с IE8.

Где container — это id элемента, который необходимо прокрутить. Т.е. в нашем случае — div или table, внутри которого располагается элемент. Как можно понять, данный скрипт выполнит прокрутку по горизонтали.

Firefox may die

Проблема:
Firefox Driver мог быть примером для остальных драйверов, но у него есть один очень неприятный недостаток. Как можно понять по коментариям к разным версиям WebDriver’a — этот недостаток, то исчезает, то вновь появляется от версии к версии.
Суть в том, что иногда на Firefox находит бес и он вдруг, без каких либо внешних, как это кажется, воздействий и изменений, начинает падать на ровном месте.
Выглядит это примерно так: вы наблюдаете, как в окне браузера успешно выполняется уже отлаженный до блеска тест. И тут на абсолютно мелочном шаге или действии окно браузера просто исчезает. В логах вы обнаруживаете такую запись: Error communicating with the remote browser. It may have died. Все, больше никакой информации вы не найдете.

Решение:
Это регрессивная ошибка и гарантированного лекарства быть не может. Заключается она в том, что между браузером и драйвером возникает непонимание. К примеру по причине того, что ваш браузер обновился, вы не обратили на это внимание и продолжаете использовать старый WebDriver. Между Firefox и его драйвером есть, как я это ощутил, зависимость. Она не абсолютная, т.е. не всякий раз когда Firefox обновился, нужно бежать обновлять вебдрайвер тоже. Но первое что я посоветую сделать — погуглите, какая версия вебдрайвера наиболее подходит под вашу версию Firefox.
В случае с Firefox 19 мне помогло обновить stand-alone-server селениума до версии 2.30.0.

Заключение

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

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

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

Источник

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

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