Разделы портала

Онлайн-тренинги

.
Инструменты для автоматизации функционального тестирования веб-приложений
05.12.2008 15:22

Автор: Семенкин Максим

Оригинальная публикация

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

htmlunit

Сайт продукта

Пример теста с сайта продукта

public void testHomePage() throws Exception {
final WebClient webClient = new WebClient(BrowserVersion.MOZILLA_1_0);
final URL url = new URL("http://htmlunit.sourceforge.net");
final HtmlPage page = (HtmlPage)webClient.getPage(url);
assertEquals( "htmlunit - Welcome to HtmlUnit", page.getTitleText() );
}

Продукт эмулирует поведение браузера через HTTP запросы. Для большинства HTML элементов предоставляется соответствующий объект с набором свойств и методов, через которые удобно анализировать и управлять HTML документом. Например, чтобы оправить данные формы и получить результаты нужно выполнить примерно следующее:

final HtmlPage page2 = (HtmlPage)button.click(); 

Из недостатков можно выделить следующее:

  • неудовлетворительная поддержка JavaScript (используется движок rhino). DHTML, AJAX - тестировать с его помощью практически не возможно. Из личного опыта - приходилось принудительно отключать эту поддержку JavaScript в htmlunit, чтобы избежать нежелательных побочных эффектов.
  • по причине выше изложенного, невозможно тестировать на совместимость в разных браузерах, хотя в продукте такая возможность заложена.

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

httpunit

Сайт продукта

Пример теста с сайта продукта:

WebConversation wc = new WebConversation();
WebResponse resp = wc.getResponse( "http://www.httpunit.org/doc/cookbook.html" ); // read this page
WebLink link = resp.getLinkWith( "response" ); // find the link
link.click(); // follow it
WebResponse jdoc = wc.getCurrentPage();

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

jWebUnit

Сайт продукта

В настоящее продукт является надстройкой (точнее оберткой) над htmlunit и предоставляет более удобный механизм для навигации между страницами и работой сними. Также предоставляет расширенный набор assert'ов - что весьма удобно (например assertTextPresent). Основным объектом при написании тестов является WebTester - абстракция веб браузера. WebTester имеет набор методов, с помощью которых можно получить доступ к содержимому документа и управлять его состоянием (осуществлять переходы, сабмиты форм):

tester.gotoPage("login")

Архитектура продукта продукта построена таким образом, что позволяет подключать другие движки для выполнения веб тестов. В следующей следующей версии (2.0) разработчики продукта планируют включить поддержку других движков, в частности, кроме работы через htmlunit, продукт сможет работать через httpunit и Selenium RC, что может быть весьма удобно. В текущей версии, продукту присущи все недостатки, что и у htmlunit, а так же есть еще один недостаток. Обертка выставляет наружу длаеко не все методы от htmlunit. Доступ к этим методам в принципе можно получить, но это уже не документированная возможность (я про Field.Accessible(true);).

Пример теста с сайта продукта:

public void testMainPageLinks() {
beginAt("/mainPage");
assertLinkPresent("addLink");
clickLink("addLink");
assertTitleEquals("Widget Add Page");
beginAt("/mainPage");
assertLinkPresentWithText("Edit Widget");
clickLinkWithText("Edit Widget");
assertTitleEquals("Widget Edit Page");
}

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

Линейка продуктов Selenium

Сайт продукта

Основное отличие и достоинство инструментов Selenium - тесты Selenium выполняются на живом браузере, т.е. нет эмуляции поведения браузера как в предыдущих продуктах. Это автоматически снимает основные недостатки вышеописанных инструментов связанных с выполнением JavaScript.

Selenium Core

Selenium встраивает JavaScript ядро (Selenium Core) посредством iframe в браузер и через это ядро выполняет тестирование веб приложения. Ядро имеет "подкрутки" учитывающие специфику различных браузеров и в настоящее время может работать со следующими:

  • Windows:
    • Internet Explorer 6.0
    • Firefox 0.8 to 1.5
    • Mozilla Suite 1.6+, 1.7+
    • Seamonkey 1.0
    • Opera 8
  • Mac OS X:
    • Safari 1.3+
    • Firefox 0.8 to 1.5
    • Camino 1.0a1
    • Mozilla Suite 1.6+, 1.7+
    • Seamonkey 1.0
  • Linux:
    • Firefox 0.8 to 1.5
    • Mozilla Suite 1.6+, 1.7+
    • Konqueror

Тесты реализуются на Selenese - язык написания тестов в формате xHTML - здесь все довольно просто и понятно:

MyTest
open /mypage  
type nameField John Smith
click submitButton True
verifyText name John Smith

Исходный код выглядит вот так:

<table class="table" border="1">
<tr><td colspan="3">MyTest</td></tr>
<tr>
<td>open</td>
<td>/mypage</td>
<td> </td>
</tr>
<tr>
<td>type</td>
<td>nameField</td>
<td>John Smith</td>
</tr>
<tr>
<td>click</td>
<td>submitButton</td>
<td>True</td>
</tr>
<tr><td>verifyText</td>
<td>name</td>
<td>John Smith</td>
</tr>
</table>

Для запуска тестов существует TestRunner - HTML/JavaScript приложение, которое умеет выполнять скрипты Selenese/группы скриптов и выдавать результаты. Есть режим пошагового выполнения.

Для написания скриптов можно применять простой текстовый редактор либо воспользоваться Selenium IDE.

Selenium IDE

Это визуальное средство для создания, отладки и запуска тестов Selenium. Реализован как плагин для Firefox. После нажатия кнопки "Запись" происходит отслеживание всех действий пользователя связанных с навигацией и вводом данных в браузере. Результаты работы сохраняются в виде скрипта Selenese. Вот как он может выглядеть:

Стоит отметить, что результаты работы могут быть сохранены также в виде сценария на языке Java(!), который в дальнейшем может быть воспроизведен с помощью Selenium RC.

Selenium RC (Selenium Remote Control)

Selenium Remote Control является сервером (написан на Java), который предоставляет удаленный интерфейс, через который можно выполнять тесты Selenium. Через определенные команды, Selenium RC может запускать и закрывать веб браузер. Как все это взаимодействует (картинка с сайта продукта):

Обращаться к удаленному интерфейсу можно из разных языков: Java, .NET, Perl, Python или Ruby. Пример теста на Java:

import com.thoughtworks.selenium.*;
import junit.framework.*;
public class GoogleTest extends TestCase {
private Selenium sel;
public void setUp() {
sel = new DefaultSelenium("localhost",
4444, "*firefox", "http://www.google.com");
sel.start(); //запуск браузера
}

public void testGoogle() {
sel.open("http://www.google.com/webhp");
sel.type("q", "hello world");
sel.click("btnG");
sel.waitForPageToLoad("5000");
assertEquals("hello world - Google Search", sel.getTitle());
}

public void tearDown() {
sel.stop(); //останов браузера
}
}

Как я упоминал выше, Selenium IDE может сохранять результаты в виде сценария Java. Относительно данного примера, тело метода testGoogle может быть легко сгенерировано визуально. Это я все к тому, что с помощью Selenium RC можно быстро генерировать черновой вариант на Java и в дальнейшем доводить его до нужной кондиции в классической Java IDE.

Помимо неоспоримых достоинств, продукту присущи и недостатки.

  • для выполнения тестов, ко всему прочему нужно запускать Selenium RC как отдельный процесс. Было бы удобно, если вызовы через JavaAPI происходили без участия Selenium RC. Как вариант, можно попытаться стартовать Selenium RC при инициализации тестов (setUp).
  • не удалось стандартным образом протестировать поля форм, которые реализованы в виде WISIWIG (TinyMCE в частности). Выход разумеется есть (присвоение значений таким полям через выполнения JS функции), но это уже не стандратное решение. Полагаю, что данный недаостаток будет устранен в дальнейших версиях продукта.

Вывод: продукт лучше чем другие (выше перечисленные) подходит для функционального тестирования и я могу его однозначно рекомендовать.

Floyd

Сайт продукта

В отличии от Selenium, который управляет браузером через JavaScript, данный продукт производит тестирование веб приложений, используя native API, который предоставляют большинство современных веб браузеров. Доступ к API браузеров осуществляется через JExplorer и JRex - повидмому работают через JNI. Поработать с данным продуктом не удалось, поэтому объективно говорить о его достоинствах и недостатках сложно. Поэтому буду делать выводы основываясь на прочитанном в документации.

Проблем с тестированием JavaScript - возникать не должно. Так же, точно можно тестировать на совместимость в IE и Firefox. Разарботчики продукта подсказали интересный подход для тестирования - тесты самостоятельно запускают сервер приложений (например Jetty) и выполняют тестирование на нем. Это нам дает возможно анализировать состояние приложения (например сессию) и откатывать данные, которые появились в БД в результате прохождения функциональных тестов.