Selenium 2. Remote Control vs Webdriver

в 11:26, , рубрики: selenium, webdriver, автоматизация тестирования, тестирование, метки: , ,

Инструмент автоматизации функционального тестирование веб-интерфейсов Selenium 2 включает в себя два продукта: Selenium Remote Control (Selenium 1) и Webdriver.
Отличаются RC и Webdriver тем, что RC взаимодействует с браузером с помощью Selenium Core — специального инструмента, который может работать с любым браузером через JavaScript. Webdriver же использует нативный интерфейс, что позволяет более точно повторять действия пользователя, однако для взаимодействия с каждым отдельным браузером нужен специальный драйвер (т.к. у каждого браузера свой собственный нативный интерфейс), но при этом скорость прохождения теста повышается. На данный момент существуют такие драйвера:

  • HtmlUnitDriver — универсальный драйвер, не требующий установки браузера;
  • FirefoxDriver — драйвер для Firefox;
  • InternetExplorerDriver — драйвер для IE;
  • ChromeDriver — драйвер для Google Chrome;
  • OperaDriver — драйвер для Opera;
  • SafariDriver — драйвер для Safari;
  • AndriodDriver — драйвер для мобильного браузера на Android;
  • IphoneDriver — драйвер для мобильного браузера на iPhone;

Использование нативного интерфейса также причиняет набольшое неудобство — любое нажатие клавиши в процессе прохождения может «обрушить» тест.

Как преимуществом, так и недостатком Selenium RC есть использование Selenium Server Standalone. С одной стороны использование сервера упрощает логирование результатов, что существенно упрощает написание автотестов(на Webdriver приходится ставить различные «костыли», чтобы выяснить где именно произошла ошибка потому, как из-за скорости прохождения тестов это не всегда можно определить визуально), но с другой стороны — увеличивается время прохождения теста и невозможность использовать для тестирования страниц на мобильном устройстве.

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

Отдельно стоит сказать о работе с JavaScript и AJAX. В Webdriver реализованы механизма ожидания завершения AJAX-запросов: Explicit Waits (явные ожидания) и Implicit Waits (неявные ожидания) (Подробнее здесь Ожидания в Webdriver). В RC для ожидания AJAX приходится использовать средства языка программирования. Также стоит отметить, что Remote Control не всегда корректно работает с JS. Например, selenium.click не может вызвать JS-ивент onMouseDown и приходится гадать, «что же там использовал разработчик?» чтобы написать корректную команду. С Webdriver подобные проблеммы не возникают.

В Selenium Remote Control в процессе развития сформировался достаточно широкий набор комманд, в то время как в Webdriver почти всё сводится к .click или .sendKeys (вобшем-то реальный пользователь может сделать не намного больше, однако, например, простая комманда для снятия скриншота или выбора Ok/Cancel в диалоговом окне не помешала бы). Однако в Webdriver реализовано большее количество локаторов для поиска элемента на странице.

By.id — обращается к элементу по ID;
By.name — обращается по имени элемента name:
By.xpath — обращается к элементу по xpath выражению;
By.tagName — поиск по имени HTML тэга;
By.cssSelector — данный тип локаторов основан на описаниях таблиц стилей (CSS);
By.className — поиск по CSS классу элемента;
By.linkTex — поиск ссылки по тексту;
By.partionalLinkText — поиск ссылки по части текста;

Рассмотрим примеры тестов на RC и Webdriver (Java).

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

Remote Control:

import org.openqa.selenium.Keys;

import com.thoughtworks.selenium.SeleneseTestCase;

import java.util.concurrent.TimeUnit;

import java.awt.event.KeyEvent;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileWriter;

import java.io.Writer;

    public class FirstTest extends SeleneseTestCase {

              public void setUp() throws Exception {

                    setUp("http://google.com", "*firefox");

                     }

            public void testGoogle() throws Exception {

             File file = new File("путь куда сохрянять лог сервера");

             if (file.exists()) {

             file.delete();

              }

             selenium.open("/"); //переход на сайт Google

             selenium.windowMaximize(); //разворачиваем окно на весь экран

             selenium.waitForPageToLoad("30000"); //ожидание загрузки страницы

             selenium.type("name=q", "zerg rush"); //ввод текста в строку поиска

             selenium.click("name=btnG"); //нажатие кнопки поиска

             TimeUnit.SECONDS.sleep(5); //задержка 5 секунд

             selenium.captureEntirePageScreenshot("путь куда сохрянять скриншоты", "");

             Writer output = new BufferedWriter(new FileWriter(file));

             output.write(selenium.getLog());

             output.close();

             System.out.println("Test Complete"); //сообщение о завершении теста
     }
 }

Webdriver

import java.util.regex.Pattern; 

import java.util.concurrent.TimeUnit;

import org.junit.*;

import static org.junit.Assert.*;

import static org.hamcrest.CoreMatchers.*;

import org.openqa.selenium.*;

import org.openqa.selenium.firefox.FirefoxDriver;

import org.openqa.selenium.support.ui.Select;

import java.awt.event.KeyEvent;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileWriter;

import java.io.Writer;

import org.apache.commons.io.FileUtils;

             public class First_test {

             private WebDriver driver;

             private String baseUrl;

             private StringBuffer verificationErrors = new StringBuffer();

             @Before

             public void setUp() throws Exception {

              driver = new FirefoxDriver();

              baseUrl = "http://google.com";

              driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); //установка длительности таймаутов

             }   
             @Test

              public void testGoogle() throws Exception {

              driver.get(baseUrl + "/"); //переход на сайт Google. ссылка забита в переменную baseUrl

              driver.findElement(By.name("q")).sendKeys("zerg rush"); //ввод текста в строку поиска

              driver.findElement(By.name("btnG")).click(); //нажатие кнопки поиска

              TimeUnit.SECONDS.sleep(5); //задержка 5 секунд

              File file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); 

              String path = "путь куда сохрянять скриншоты";

              FileUtils.copyFile(file, new File(path));

              System.out.println("Test Complete"); //сообщение о завершении теста

              }             

              @After

              public void tearDown() throws Exception {

              driver.quit();

              String verificationErrorString = verificationErrors.toString();

              if (!"".equals(verificationErrorString)) {

              fail(verificationErrorString);

     }

   }

              private boolean isElementPresent(By by) {

               try {

               driver.findElement(by);

               return true;

               } catch (NoSuchElementException e) {
              return false }

   }

}

Из всего выше сказанного видно, что и Remote Control и Webdriver имеют как недостатки так и преимущества. В большом количестве случаев удобнее использовать RC, т.к. большой набор комманд и возможность работать со скрытыми элементами, а также возможность получать логи сервера существенно упрошают и ускоряют (время — деньги) процесс написания и последующего адаптирования тестов. Webdriver же уместно использовать там, где не справляется (плохо справляется) RC, например для перегруженых AJAX-запросами веб интерфейсов или в местах где крайне вожно точно симитировать действия пользователя (следует заметить, что Webdriver и был внедрён потому, что с появлением более новых веб-технологий Selenium RC просто исчерпал себя и необходимость в альтернативном подходе стала очевидной).

Также в Selenium 2 реализована возможность перехода с RC на Webdriver. Подробно описан в оф. документации.

Автор: shuri_x

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js