Статьи

Selenium 2 / Веб-Драйвер — Земля, где Page объекты являются королем!

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

Selenium 2, как и Selenium, является кросс-браузерным инструментом — он одинаково рад работать как с Firefox, так и с Internet Explorer. Но он также работает с HTMLUnit, который имитирует браузер, отправляя HTTP-запросы и анализируя HTML-ответы. Вы можете выбрать один из нескольких драйверов, включая HTMLUnit (который отлично подходит для быстрого тестирования более традиционных веб-приложений), а также драйверы на основе браузера для Firefox, Chrome и InternetExplorer. Базовый API идентичен, хотя пробег зависит от одного драйвера к другому, особенно если вы тестируете приложения на основе AJAX — например, тесты для некоторых приложений AJAX будут работать с браузером Firefox, но не с браузером HTMLUnit. Хорошей новостью является то, что переключаться между водителями тривиально просто.

Настроить Selenium 2 в проекте Maven очень просто: просто добавьте следующую зависимость:

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium</artifactId>
<version>2.0a5</version>
</dependency>

Это даст вам основные библиотеки Selenium 2 плюс все драйверы.

В Selenium 2 простой веб-тест может выглядеть так:

@Test
public void theUserShouldBeAbleToTypeInQueryTerms() {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com");
WebElement queryField = driver.findElement(By.name("q"));
queryField.sendKeys("cats");
queryField.submit();
assertThat(driver.getTitle(), containsString("cats"));
}

В этом тесте Webdriver запустит экземпляр Firefox и откроет соединение с Google. Затем он введет слово «кошки» в поле запроса (
имя атрибута которого «q»). Наконец, мы отправляем прилагаемую форму и проверяем, что заголовок страницы теперь содержит слово «кошки».

Пользователи Selenium заметят, что API гораздо более объектно-ориентирован и читается более плавно, чем более старый API Selenium 1. Он также проще и легче в освоении, чем значительный Selenium API.

Как упоминалось ранее, API практически идентичен, независимо от того, какой браузер вы используете. Если вы хотите использовать вместо этого HTMLUnit, просто измените драйвер:

@Test
public void theUserShouldBeAbleToTypeInQueryTerms() {
WebDriver driver = new HTMLUnitDriver();
driver.get("http://www.google.com");
WebElement queryField = driver.findElement(By.name("q"));
queryField.sendKeys("cats");
queryField.submit();
assertThat(driver.getTitle(), containsString("cats"));
}

Теперь, в реальном мире, есть исключения, и иногда вы можете захотеть использовать некоторые из более продвинутых функций, которые может предложить только драйвер на основе браузера, такой как FirefoxDriver: к ним относятся некоторые функции AJAX, перетаскивание и перетаскивание и выяснить, является ли объект на странице видимым или нет. Но, в целом, API эффективно кросс-браузерный.

Еще одна приятная особенность по сравнению с Selenium 1 — отсутствие церемоний, необходимых для выполнения теста. Этот тест будет работать как есть, без дополнительной сантехники, инфраструктуры или скрытых проводов. Для эквивалентного теста Selenium 1 вам необходимо запустить сервер Selenium-RC перед запуском теста, который является относительно медленным и иногда непостоянным процессом. В Selenium 2 это больше не требуется — вы можете написать этот тест в Eclipse и запустить его изолированно, и он будет работать просто отлично.

FindElement образец , который мы видели ранее , оказывается чрезвычайно мощным средством моделирования и проверки веб — страниц, и вы можете делать то , что вы могли только мечтать в Selenium 1. Например, следующая таблица результатов приходит из приложения ICEfaces JSF :

<table class="iceForm:iceTable">
<tr>
</tr>
<tr class="bidTableRow oddRow">
<td class="column1">ICEsoft Ice Sailor</td>
<td class="column2">$10,000.00</td>
<td class="column3">0</td>
...
</tr>
<tr class="bidTableRow evenRow">...</tr>
<tr class="bidTableRow oddRow">...</tr>
<tr class="bidTableRow evenRow">...</tr>
</table>

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

WebElement table = driver.findElement(By.id("iceForm:iceTable"));
List rows = table.findElements(By.className("bidTableRow"));
for(WebElement row : rows) {
String name = row.findElement(By.className("column1")).getText();
String price = row.findElement(By.className("column2")).getText();
String bids = row.findElement(By.className("column3")).getText();
// Do something with the row data
}

But where Selenium 2 really shines is in its support for Web Objects. Web Objects are a technique that involves modeling your user interface in the form of classes, with meaningfully-named fields and methods. This makes the tests more readable by isolating them from the implementation details, and also allows a better use of a business-friendly vocabulary. Here is a simple Page Object, which models the Google search page:

public class GoogleSearchPage {

protected WebDriver driver;

private WebElement q;

private WebElement btnG;

public GoogleSearchPage(WebDriver driver) {
this.driver = driver;
}

public void open(String url) {
driver.get(url);
}

public void close() {
driver.quit();
}

public String getTitle() {
return driver.getTitle();
}

public void searchFor(String searchTerm) {
q.sendKeys(searchTerm);
btnG.click();
}

public void typeSearchTerm(String searchTerm) {
q.sendKeys(searchTerm);
}

public void clickOnSearch() {
btnG.click();
}
}

Хотя этот класс не очень полезен в отдельности, Selenium 2 предоставляет способ сопоставить его с реальной веб-страницей. Класс PageFactory предоставляет удобный способ инициализации полей объекта Page.

public class WhenAUserSearchesOnGoogle {

private GoogleSearchPage page;

@Before
public void openTheBrowser() {
page = PageFactory.initElements(new FirefoxDriver(), GoogleSearchPage.class);
page.open("http://google.co.nz/");
}

@After
public void closeTheBrowser() {
page.close();
}

@Test
public void whenTheUserSearchesForCatsTheResultPageTitleShouldContainCats() {
page.searchFor("cats");
assertThat(page.getTitle(), containsString("cats") );
}
}

По умолчанию он сопоставляет свойства объекта страницы с полями с совпадающими идентификаторами или именами, поэтому приведенный здесь пример будет работать нормально из коробки. Но иногда нам нужно больше контроля над идентификацией элементов на странице HTML и отображением их в наших полях Page Object. Один из способов сделать это — использовать аннотацию @FindBy , как показано в следующем коде:

public class GoogleSearchPage {

protected WebDriver driver;

@FindBy(id="q")
private WebElement searchField;

@FindBy(name="btnG")
private WebElement searchButton;

public AnnotatedGoogleSearchPage(WebDriver driver) {
this.driver = driver;
}

public void open(String url) {
driver.get(url);
}

public void close() {
driver.quit();
}

public String getTitle() {
return driver.getTitle();
}

public void searchFor(String searchTerm) {
searchField.sendKeys(searchTerm);
searchButton.click();
}

public void typeSearchTerm(String searchTerm) {
searchField.sendKeys(searchTerm);
}

public void clickOnSearch() {
searchButton.click();
}
}

Selenium 2 / Web Driver предоставляет множество мощных функций в очень чистом API — фактически, мы только что коснулись этой статьи. В следующих статьях я буду обсуждать тестирование приложений AJAX с WebDriver и написание собственных тестовых DSL с помощью инструментов WebDriver и BDD, таких как easyb . Так что следите за обновлениями! В то же время, если вы серьезно относитесь к автоматическому веб-тестированию, вам действительно стоит попробовать его.

Если вы хотите узнать больше о Selenium 2 / WebDriver, обязательно посетите предстоящие учебные семинары по TDD / BDD (которые пройдут в Канберре, Веллингтоне и Сиднее) и загрузочные лагеря Java Power Tools (которые скоро появятся в Лондоне и Канберре). ) — оба эти курса включают новый Selenium 2 / WebDriver. Мы также запускаем этот модуль по запросу в качестве дневного курса. Проверьте это!

От http://weblogs.java.net/blog/johnsmart/archive/2010/08/09/selenium-2web-driver-land-where-page-objects-are-king