t.me/atinfo_chat Telegram группа по автоматизации тестирования

Немного о Selenium WebDriver


(Mykhailo Poliarush) #1

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.

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

  • FirefoxDriver;
  • InternetExplorerDriver;
  • ChromeDriver;
  • OperaDriver – в данный момент еще не доступен для использования;
  • SafariDriver – в данный момент еще не доступен для использования;;
  • HtmlUnitDriver – кроссплатформенный драйвер на java, не требует установки кого-либо браузера;
  • AndriodDriver – мобильный браузер. Возможность тестирования веб-приложений под телефоны – еще одна фишка в Selenium 2.0;
  • IphoneDriver – мобильный браузер.

Список поддерживаемых языков в Selenium WebDriver: C#, Java, Ruby, Phyton.

Про основные команды в Selenium WebDriver я постараюсь написать в следующих заметках, стоит лишь отметить, что некоторые принципы работы по сравнению c Selenium 1.0 все же изменились в лучшую сторону. Так, WebDriver предлагает достаточно гибкую работу с ожиданиями событий на странице. Это объясняется тем, что WebDriver направлен в первую очередь на работу со сложным, перегруженными AJAX запросами веб-интерфейсами. Разработчики предлагают два механизма ожидания (Explicit Waits, Implicit Waits), тут можно посмотреть описание и примеры. Explicit Waits (эксплицитное ожидание), с использованием класса WebDriverWait, представляет сабой фактически циклическое ожидание события. Implicit Waits (имплицитное ожидание) – все команды поиска элементов автоматически становятся ожидающими. Естественно, можно использовать свои методы ожидания, ну или (что очень не желательно :-) ) Thread.sleep(). Кстати, Selenium WebDriver умеет работать с HTML 5! Также, очень порадовал измененный механизм работы с локаторами – работать стало гараздо удобнее. В Selenium WebDriver добавились новые типы локаторов: partionalLinkText, tagName, name. Не поддерживаются dom локаторы. В этой заметке я расписывал типы локаторов в Selenium 1.0. Полный список локаторов в Selenium 2.0:

  • By.id – в качестве локатора используется атрибут id (уникальный идентификатор) элемента страницы;
  • By.name – в качестве локатора используется атрибут name элемента страницы;
  • By.xpath – используется для поиска элемента по XPath выражению;
  • By.tagName – поиск по имени HTML тэга;
  • By.className – поиск по CSS классу элемента;
  • By.cssSelector – данный тип локаторов основан на описаниях таблиц стилей (CSS);
  • By.linkText – поиск ссылки с указанным текстом;
  • By.partionalLinkText – поиск по части ссылки с указанным текстом.

Для того, чтобы начать разрабатывать авто тесты на Selenium 2.0 под .Net нужно скачать отсюда набор библиотек для .Net. В скачанном архиве должны находится следующие библиотеки: Castle.Core.dll, Ionic.Zip.Reduced.dll, Newtonsoft.Json.Net35.dll, Selenium.WebDriverBackedSelenium.dll, ThoughtWorks.Selenium.Core.dll, WebDriver.dll, WebDriver.Support.dll. Данные библиотеки нужно подключить в проект. Если вы хотите писать тесты на другом языке программирования, то начальную инструкцию, можно изучить на официальным сайте разработчиков Selenium. Для запуска тестов, нам понадобиться установить NUnit. NUnit – это вспомогательный framework для создания тестов. Скачать NUnit можно перейдя по этой ссылке. Библиотеки NUnit: nmock.dll, nunit.core.dll, nunit. framework.dll также нужно подключить в проект.

Итак, открываем Visual Studio и создаем новый проект типа Class Library, добавляем упомянутые выше библиотеки. После этого можно приступать к написанию первого теста. Шаги нашего простейшего теста будут следующими:

  • Открыть главную страницу данного блога, проверить title страницы;
  • В поле “Поиск” внести значение “Selenium WebDriver”;
  • Нажать на кнопку “Search Submit” (лупа);
  • Проверить результаты поиска.

Пример теста на Selenium WebDriver с использованием C#:


using System;
using System.Text;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
 
namespace SeleniumTests
{
    [TestFixture]
    public class Untitled
    {
        private IWebDriver driver;
        private StringBuilder verificationErrors;
        private string baseURL;
 
        [SetUp]
        public void SetupTest()
        {
            // You may use any WebDriver implementation. Firefox is used here as an example
            driver = new FirefoxDriver();
            baseURL = "http://bugscatcher.net";
            verificationErrors = new StringBuilder();
        }
 
        [TearDown]
        public void TeardownTest()
        {
            try
            {
                driver.Quit();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
            Assert.AreEqual("", verificationErrors.ToString());
        }
 
        [Test]
        public void TheUntitledTest()
        {
            // open | /qa |
            driver.Navigate().GoToUrl(baseURL);
 
            // assertTitle | Bugs Catcher |
            Assert.AreEqual("Bugs Catcher", driver.Title);
 
            // type | name=s | Selenium WebDriver
            driver.FindElement(By.Name("s")).SendKeys("Selenium WebDriver");
 
            // click | id=searchsubmit |
            driver.FindElement(By.Id("searchsubmit")).Click();
 
            // assertTitle | Search Results Selenium WebDriver -Bugs Catcher |
            Assert.AreEqual("Search Results Selenium WebDriver -Bugs Catcher", driver.Title);
 
            //assertText present
            Assert.IsTrue(driver.PageSource.Contains("Результаты поиска"));
 
            //assertLink present
            driver.FindElement(By.LinkText("Выпуск Selenium 2.0"));
        }
    }
}

Теперь попробуем запустить разработанный тест. Перед этим сбилдите проект в Visual Studio  и проверьте, что нет ошибок. Если все хорошо, идем дальше, если нет – пишите в комменты или на email.

  • Запускаем ранее установленный NUnit;
  • В NUnit выбираем “File -> Open Project…”;
  • И в диалоговом окне указываем путь к .dll нашего теста (…binDebugSeleniumTest.dll);
  • Загружаем проект и нажимает кнопку “Run” (ее будет трудно не заметить).

В результате данных не итрых действий должен запуститься написанный нами ранее авто-тест на Selenium. Примерно так должно выглядеть окно NUnit-а с загруженным тестом:

В данном примере использовались следующие команды Selenium WebDriver:

  • void GoToUrl(string url) – перейти по указанному в “baseURL” адресу;
  • string Title { get; } – возвращает Title активной страницы;
  • FindElement(OpenQA.Selenium.By by) – поиск элемента страницы по указанному типу локатора. Например, driver.FindElement(By.Name("s")) или driver.FindElement(By.LinkText("Выпуск Selenium 2.0")). Список поддерживаемых типов локаторов предоставлен выше;
  • void SendKeys(string text) – ввести значение в текстовое поле;
  • void Click() – нажатие на элемент страницы;
  • public bool Contains(string value) – возвращает значение, указывающие, является ли введённое значение частью объекта.

Также разработчиками Selenium 2.0 создан план по переходу от Selenium 1.0 к Selenium 2.0 в режиме WebDriver. План примерно таков:

Используем эмулятор интерфейса Selenium 1.0 для Java и .Net. Для этого нужно использовать в инициализации WebDriverBackedSelenium вместо DefaultSelenium. Судя по комментариям на данном этапе могут возникать трудности (и скорее всего возникнут). Проблемы могут возникнуть в связи с тем, что команды в Selenium 2.0 немного отличаются (фиксы старых проблем, плюс теоретически новые проблемы) от Selenium 1.0. Поэтому после данной стадии скорее всего последует этап стабилизации. Должно получится примерно так:


</p><ul><li>Создание новых тестов и переписывание старых под Selenium 2.0 в режиме 
WebDriver. После того, как все тесты будут готовы работать в режиме 
WebDriver в классе инициализации Selenium вместо эмулятора <code>WebDriverBackedSelenium</code> нужно прописать команду запуска чистого WebDriver API:</li></ul><p>{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();{/syntaxhighlighter}</p><p>В качестве примера возьмем ранее рассмотренный тест и и преобразуем его 
 таким образом, чтобы можно было использовать команды как Selenium 1.0, 
так и Selenium 2.0. После этого запустим полученный тест в смешанном 
“режиме” (на всякий случай напомню, что Selenium Server запускать не 
нужно). Вот так вот будет выглядеть преобразованный тест с 
использованием команд Selenium 1.0 и Selenium 2.0 (Web Driver)  (найдите
 10 отличий от предыдущего примера <img src='/uploads/default/1176/107992ef07a5899e.gif' alt=":-)" class="mceItem"> ) :</p><p>{syntaxhighlighter brush: bash;fontsize: 100; first-line: 1; }using System;
using System.Text;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using Selenium;
 
namespace SeleniumTests
{
    [TestFixture]
    public class Untitled
    {
        private IWebDriver driver;
        private StringBuilder verificationErrors;
        private string baseURL;
        private ISelenium selenium;
 
        [SetUp]
        public void SetupTest()
        {
            // You may use any WebDriver implementation. Firefox is used here as an example
            driver = new FirefoxDriver();
 
            // A "base url", used by selenium to resolve relative URLs
            baseURL = "http://bugscatcher.net";
 
            // Create the Selenium implementation
            selenium = new WebDriverBackedSelenium(driver, baseURL);
 
            selenium.Start();
            verificationErrors = new StringBuilder();
        }
 
        [TearDown]
        public void TeardownTest()
        {
            try
            {
                selenium.Stop();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
            Assert.AreEqual("", verificationErrors.ToString());
        }
 
        [Test]
        public void TheUntitledTest()
        {
            // open | /qa |
            driver.Navigate().GoToUrl(baseURL);
 
            // assertTitle | Bugs Catcher |
            Assert.AreEqual("Bugs Catcher", selenium.GetTitle());
 
            // type | name=s | Selenium WebDriver
            driver.FindElement(By.Name("s")).SendKeys("Selenium WebDriver");
 
            // click | id=searchsubmit |
            selenium.Click("searchsubmit");
 
            selenium.WaitForPageToLoad("3000");
 
            // assertTitle | Search Results Selenium WebDriver -Bugs Catcher |
            Assert.AreEqual("Search Results Selenium WebDriver -Bugs Catcher", driver.Title);
 
            //assertText present
            Assert.IsTrue(selenium.IsTextPresent("Результаты поиска"));
 
            //assertLink present
            driver.FindElement(By.LinkText("Выпуск Selenium 2.0"));
        }
    }
}

Вот еще пример работы на совместимостью WebDriver и Selenium RC взятый из официальной документации к Selenium 2.0:


// You may use any WebDriver implementation. Firefox is used here as an example
WebDriver driver = new FirefoxDriver();
 
// A "base url", used by selenium to resolve relative URLs
 String baseUrl = "http://www.google.com";
 
// Create the Selenium implementation
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
 
// Perform actions with selenium
selenium.open("http://www.google.com");
selenium.type("name=q", "cheese");
selenium.click("name=btnG");
 
// Get the underlying WebDriver implementation back. This will refer to the
// same WebDriver instance as the "driver" variable above.
WebDriver driverInstance = ((WebDriverBackedSelenium) selenium).getUnderlyingWebDriver();
 
    //Finally, close the browser. Call stop on the WebDriverBackedSelenium instance
    //instead of calling driver.quit(). Otherwise, the JVM will continue running after
    //the browser has been closed.
    selenium.stop();

Удачной автоматизации!


(testtest) #2

Парни, отличная статья! первая которую я прочитал на этом ресурсе!

Я бы хотел только сделать её еще лучше) Заметил достаточное количество орфографических ошибок. (WebDriver кстати еще не обзавелся spellchecker'ом?;)

Было бы круто впитывать чистые светлые знания не вбивая в подкорку неправильное написание слов! Но как я уже сказал это мелочь! Вы делаете супер дело! Спасибо)


(Mykhailo Poliarush) #3

спасибо за отзыв, будем что-то думать, чтобы не пропускать ошибки