AT.info ПОСИДЕЛКИ  vKontakte   facebook группа  
Локатор

Немного о Selenium WebDriver

Selenium 2.0 – это инструмент автоматизации функционального тестирования, который включает в себя два ранее независимых проекта – Selenium Remote Control и WebDriver. В Selenium 2.0 можно использовать все прелести как Selenium WebDriver, так и Selenium RC (в режиме совместимости с WebDriver). Разработчики инструмента рекомендуют использовать Selenium WebDriver в тех местах, где не справляется Selenium RC, конечно, если нет других факторов, которые могут влиять на выбор инструмента автоматизации. При работе над Selenium 2.0 основная работа шла над Selenium WebDriver и режимом совместимости с Selenium RC. Сам Selenium RC особых изменений не претерпел, в основном фиксились старые баги, поэтому скорее всего придется переписывать некоторые тесты (убирать костыли и т.п.), если вы собираетесь использовать RC в режиме совместимости.

Главное отличие, которое разделяет WebDriver и Selenium RC, заключается в способе взаимодействия с браузером. Selenium RC посылает команды браузеру с помощью специального JavaScript ядра Selenium Core. Данный подход позволяет обеспечивать кроссбраузерность (Selenium 1.0 может с относительной легкостью работать с разными браузерами). В этой заметке я описывал инструменты тестирования семейства Selenium. WebDriver, в отличие от Selenium RC “общается” с браузером через нативный интерфейс. Для каждого браузера свой нативный интерфейс, это и накладывает определенные сложности с поддержкой разных браузеров в WebDriver. Зато, предоставляет ряд преимуществ, таких как скорость работы, действия пользователя эмулируется максимально точно (например, тесты на WebDriver не видят скрытые элементы интерфейса). То есть, в Selenium 2.0 фактически объединены все достоинства (и недостатки тоже) перечисленных ранее инструментов.

Архитектуру Selenium RC можно представить следующим образом: Авто тесты -> Selenium RC Server -> Браузер -> Тестируемое приложение. Как работает Selenium RC:

В архитектуре Selenium WebDriver отсутствует “прослойка” Selenium RC Server. Зато добавляется слой Driver, который и отвечает за взаимодействие с браузером. Вот так устроен Selenium WebDriver:

Главное достоинство Selenium WebDriver заключается в том, что он использует драйверы, адаптированные под конкретный браузер, то есть Selenium WebDriver работает с каждым браузером по “индивидуальной программе”. Это повышает стабильность работы тестов (так как они затачиваются под конкретный браузер), тесты становится проще писать и поддерживать, увеличивается скорость их работы. Selenium WebDriver использует нативные команды (старается полностью эмитировать действия пользователя), что является важным преимуществом перед Selenium RC.

На данный момент существуют следующие драйверы:

Первые шаги с Selenium RC

Установка Selenium RC

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

 Тут подробнее про инструменты семейства Selenium. Скачать последнею версию Selenium RC можно с официального сайта проекта. После скачивания Selenium RC нужно просто разархивировать файлы в нужную директорию. Также для запуска Selenium Server нужно установить Java Runtime Environment (JRE) версии 1.5 и выше. Обратите внимание, что версия JRE должна быть не ниже 1.5. Чтобы проверить, установлен ли у вас JRE и какая у него версия, нужно выполнить в консоли команду: java –version

После скачки Selenium RC и установки JRE можно запускать Selenium Server. Для этого открываем директорию в которой установлен Selenium Server, запускаем консоль (“Пуск/Выполнить/cmd”). В консоли нужно выполнить следующую команду: java -jar selenium-server.jar

java -jar selenium-server.jar [options] – формат запуска Selenium Server.

[options] в формате запуска сервера- это дополнительные опции запуска Selenium Server. Более подробную информацию о параметрах запуска Selenium Server можно узнать на сайте проекта. Для запуска Selenium Server рекомендую сразу же сделать .bat файл, так будет удобнее запускать сервер. Также Selenium Server можно запускать из кода тестов. После запуска сервера у вас на экране должно появится примерно такое окно:

Запуск Selenium RC с использованием прокси

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

  • Dhttp.proxyHost – адрес (или IP), на котором находится прокси;
  • Dhttp.proxyPort – порт, через который происходит соединение;
  • Dhttp.proxyUser – имя пользователя, если требуется HTTP-прокси аутентификация;
  • Dhttp.proxyPassword – пароль пользователя, если требуется HTTP-прокси аутентификация.

Пример запуска Selenium Server с указанием прокси-сервера:

Основные команды в Selenium IDE / RC

Инструменты автоматизации функционального тестирования семейства Selenium на сегодняшний день достигли бешеной популярности. Невозможно представить специалиста по тестированию, который, как минимум, не слышал про данный инструмент. Каждый день все новые и новые специалисты по тестированию начинаю осваивать Selenium. Именно для новичков, желающих освоить основы Selenium IDE / RC, и предназначена эта заметка. В данной заметке будут представленны основные команды в Selenium IDE / RC.

Базовую информацию о инструментах автоматизации Selenium вы можете получить перейдя по этой ссылке.

В Selenium существует три типа команд:

  • Действия – функциональное действие над тестируемым веб-приложением в браузере. Например, заполнение полей, нажатие на кнопку и другие;
  • Проверки – выполнение проверок на тестируемой странице. Например, проверка того, что определенное поле формы имеет указанное значение, или проверка заголовка окна;
  • Ожидания – организация как, сколько и какое событие Selenium будет дожидаться (ожидания загрузки страницы, ajax и т.д.).

at.info workshop #2: отчет

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

Мы начали с знакомства и определения уровня собравшейся аудитории. Разъяснили базовые моменты работы Selenium и перешли к основной теме воркшопа - Локаторам.

Мы поддерживаем наш формат 95% практики и лишь 5% теории. Потому, весь материал был подкреплен практическими заданиями, с которыми ребята успешно справились. И ушли домой со всеми материалами, полученными во время встречи. 

Почему CSS локаторы работают быстрее чем XPath?

Посмотрел я видео, где рассказывают о CSS vs XPath. 

http://www.youtube.com/watch?v=6vPu3TO6XZ4&feature=channel_video_title

Мне стало интересно, почему практически во всех случаях XPath работает медленее (пуская в доли секунды для FireFox или секунды для Internet Explorer) чем CSS?

Selenium: Подбираем локаторы

Знание типов локаторов - это только первый шаг к умению рационально их использовать. Умение же ими пользоваться - один из ключевых навыков работы с Selenium-ом, так как всё остальное, что необходимо знать, сводится к изучению библиотеки (а основного функционала там немного) и ряда частных случаев, как правило, обходных маневров. Всё остальное уже больше относится к умению работать с тем или иным языком программирования. Поэтому в данном разделе мы рассмотрим, какой локатор и в каком случае удобнее подобрать.

В принципе, локаторы можно расположить по приоритетам использования в следующем порядке:

  • link= (только для ссылок, естественно, причем при условии, что данная ссылка одна, а не серия)
  • id=
  • name=
  • dom=
  • css=
  • xpath=

Соответственно, когда мы подбираем локатор для некоторого элемента, мы смотрим на его HTML-код и ищем реквизиты:

  • Текст элемента (для статических ссылок это чуть ли не ключевой элемент, для других элементов это как минимум основа для XPath, но вначале лучше смотреть на что-то другое)
  • Атрибут id
  • Атрибут name
  • Соседние или вышестоящие по иерархии элементы, у которых более-менее четко находится хотя бы один из вышепереисленных атрибутов

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

К этим частным случаям можно отнести следующие:

  1. Отдельная ссылка либо с фиксированным текстом, либо с некоторой фиксированной частью
  2. Стандартный элемент управления формы
  3. Некоторый элемент в таблице, содержащей множество таких же однородных элементов

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

Отдельная ссылка либо с фиксированным текстом, либо с некоторой фиксированной частью

Отдельная ссылка с фиксированным текстом

Итак, у нас есть ссылка на странице и мы четко знаем, что она такая одна. Для примера, допустим, у нас есть ссылка

<a href="www.somedomain.com">Sample Link</a> 

Теперь подберем локатор, наиболее подходящий для нее, исходя из приоритетов выбора локаторов выше. Что у нас там? Локатор вида link=.

  1. Применяется для ссылок? Да
  2. Использует фиксированный текст ссылки? Да
  3. Идентифицирует ли он этот объект уникально? Да (по условию, такая ссылка одна на странице).

Selenium-RC: дружим с CSS

Безусловно, XPath-локатор является одним из наиболее универсальных и наиболее точных локаторов. Но к этой универсальности добавляется один из главнейших недостатков данного типа локаторов - низкая скорость обнаружения данного элемента. Это наиболее хорошо проявляется под IE, в то время как тот же Firefox работает нормально. Это связано с внутренними особенностями браузеров, в частности в способе аллоцирования элементов страницы. Но суть не в этом. Суть в том, что Селениум-тесты, которые интенсивно используют XPath работают крайне медленно под IE. И это вызывает ряд проблем как со скоростью выполнения тестов, так и с качеством этих тестов, особенно при работе с динамическим контентом. Как альтернатива XPath могут рассматриваться CSS локаторы. Что с ними можно делать?

Во-первых, CSS-локаторы тоже позволяют привязаться к иерархии объекта. Например, такой XPath-локатор:

xpath=//div//span/a

может быть описан через CSS вот так:

css=div * span > a

Отсюда четко прослеживается аналогия элементов XPath и CSS, а именно:

  1. Знак "/", означающий следующий уровень иерархии объекта, соответствует оператору ">" в CSS.
  2. Знак "//", означающий любой элемент, находящийся по иерархии ниже текущего, соответствует оператору "*" в CSS

Во-вторых, как и в XPath, CSS-локаторы могут привязываться к значениям атрибутов. Например, такой XPath-локатор:

xpath=//div[@id="some_id"]

может быть описан через CSS вот так:

css=div[id=some_id]

Также есть возможность проверки на частичное совпадение значения атрибута. Но здесь CSS немного ограничен. Есть возможность проверки, что значение атрибута содержит несколько слов, разделенных пробелами, но одно из них четко соответствует значению. То есть, то, что в XPath может быть выражено вот так:

xpath=//div[contains(@title="title")]

через CSS выражается вот так:

css=div[@title~=title]

Selenium RC: Дружим с XPath

При работе с Selenium доступ к объектам осуществляется через локаторы - строки, идентифицирующие объект, над которым проводится то или иное действие. Наиболее удобными и наиболее быстрыми являются локаторы, определенные по ID объекта ( у каждого объекта на HTML странице может быть определен атрибут ID, причем он должен быть уникальным ). Ну уж если не определен ID, то как минимум для элементов форм есть атрибуты Name, через которые тоже достаточно удобно и просто работать. Но в общем случае, приходится работать с большим многообразием объектов, причем и действия приходится делать самые разнообразные. Например: 

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

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

  1. Во-первых, данный способ задания местоположения объекта оперирует с фактическими HTML-тегами, что дает возможность формировать локаторы исходя из непосредственно HTML-кода страницы, который можно просмотреть.
  2. Во-вторых, есть возможность задать некоторую иерархию объектов, при этом пропустить варьируемые элементы (удобно, когда надо вычислить элемент внутри таблицы, не привязываясь к конкретным ячейкам).
  3. В-третьих, элемент можно задать используя как теги, так и определенные значения атрибутов, причем можно проверить на частичное соответствие (удобно, когда элемент уникально идентифицируется обработчиком некоторого события). 
  4. В-четвертых, в Selenium есть отдельный метод, который позволит нам узнать количество элементов, удовлетворяющих заданному XPath, а такде возможность использовать индексы, что позволяет выделить и перебирать целую коллекцию элементов.

А теперь перейдем к практической составляющей. Допустим, у нас есть набор различных графиков в виде bar-chart или pie-chart, причем при клике на каждый элемент происходит переход на некоторую страницу. Реализация в HTML подобного имеет вид:

<map>
      <area href="ref1">
      <area href="ref2">
      <area href="ref3">
      ...
      <area href="ref1">
      <img src="some_img.gif"> 
</map>

вот таких map-блоков произвольное количество. В каждом из этих блоков произвольное количество элементов area. Но везде есть ссылки и на эти area-объекты мы можем сделать клик. Итак, как можно организовать обработку всех активных областей всех диаграмм. Вначале, мы узнаем, сколько же всего этих диаграмм присутствует. Предположим, что у нас уже есть проинициализированный объект Selenium-a и мы уже на нужной странице. Соответственно, реализация имеет вид (далее все примеры приводятся с использованием синтаксиса Java, но по аналогии переносится на остальные языки, на которых реализован Selenium-клиент):

int chartsCount = selenium.getXPathCount( "//map" ).intValue();

Selenium RC (Ruby): Вынесение оконных деклараций в XML-файл

Одной из наиболее серьезных проблем при автоматизации функционального тестирования на уровне GUI является высокая чувствительность тестов к изменениям GUI. По-хорошему, подобная ситуация не должна возникать, так как автоматизация подобного рода ставится тогда, когда пользовательский интерфейс более-менее стабилен. Но это идеальная ситуация. В реальности, продукт меняется по всем направлениям и в том числе это касается пользовательского интерфейса. Так или иначе какие-то мелкие изменения имеют место (поле переименовали, переместили, поменяли некоторые идентификаторы) и это уже влияет на работоспособность тестов. Частично, можно реализовать гибкий механизм поиска объектов, на который подобные изменения не повлияют, но в большинстве случаев корректировок самих реализаций тестов не избежать. Соответственно, надо как-то минимизировать трудозатраты на корректировку. Наиболее эффективным решением данной проблемы можно назвать вынесение оконных деклараций во внешний ресурс и использование "псевдонимов". Подобное реализовано в WinRunner ( GUI Map ), QTP, RFT ( в котором есть возможность маппинга и все оконные объекты можно классифицировать как mappable и non-mappable ), TestComplete ( NameMapping и Alias, появившийся в поздних версиях ). Суть подобных решений в том, чтобы некоторому оконному объекту с заданными атрибутами поставить в соответствие некоторое имя, которое и будет использовано для обращения к данному оконному объекту.

Во многих средствах подобный механизм реализован, но существует много различных решений, которые фактически представляют собой некоторую библиотеку с прикрученным тестовым движком. В этом случае приходится пользоваться возможностями языка, на котором эти тесты пишутся. В качестве примера рассмотрим язык Ruby и конкретно его порт под Selenium RC. Почему взят именно Ruby? Во-первых, на Ruby есть еще несколько решений аналогичных Selenium RC и возможности языка, там применимы в той же мере. Во-вторых, Ruby - один из примеров языков интерпретируемого типа, у которого есть возможность динамического формирования и компоновки объектов. Подобные механизмы имеются и во многих других скриптовых языках ( в частности JavaScript ), поэтому Ruby был выбран в качестве демонстрации самой возможности подобной компоновки. На других языках подобные решения реализуются по аналогии с поправкой на специфику.

Как известно, в Selenium оконные объекты распознаются с помощью локаторов - специальных строк вида:

<how>=<value>, где

how - определяет атрибут, по которому ищется объект. Это может быть id,name, dom, xpath и многие другие ( в документации по Selenium о локаторах достаточно много расписано )
value - непосредственно значение атрибута, по которому ищется объект

То есть одна строка идентифицирует объект. У подобного решения есть одно достаточно сильное преимущество - простота использования. Но подобная строка не отражает логического смысла объекта. Например, локатор

xpath=//img[@alt=‘The image alt text’]

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

<Псевдоним страницы>.<Псевдоним объекта>

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

class MyPage

     def lnkLink()
          "xpath=//img[@alt='The image alt text']"
     end

end

После чего мы можем создать экземпляр данного класса:

wTestPage = MyPage.new

и вместо локатора использовать выражение вида:

wTestPage.lnkLink

Уже проще, так как в случае модификации атрибутов ссылки нам не надо будет менять локаторы во всех тестах, достаточно будет внести корректировки в объявлении класса. Также это решение удобно тем, что оконные декларации - это такая же часть програмного кода, что и непосредственно реализации тестов. Но тем не менее, немного неудобно нагромождать большое количество подобных классов, а если тестируемое приложение содержит много страниц, то классов будет много, что влечет за собой большое количество файлов. Поэтому, зачастую целесообразно отделить ресурсы ( оконные декларации ) от движка ( непосредственно програмной реализации ). В качестве аналога можно вспомнить NameMapping в TestComplete. Файл, описывающий правила маппинга - это XML-файл. Соответственно, можно попробовать сделать аналогичную реализацию на Ruby. Тем более в данном случае задача заметно проще, так как практически нет иерархии объектов, а сами объекты описываются одной строкой, а не множеством атрибутов.

RSS-материал