четверг, 11 марта 2010 г.

WatiN и ASP.NET integration tests

Не так давно пробовал библиотеку WatiN в работе, впечатления очень положительные.

На мой взгляд эту библиотеку очень выгодно отличает ее API. Он очень domain specific и его удобно использовать и читать.

Так же очень логично использовать так называемый "Page-based API", когда каждая страница в сценарии инкапсулирована в отдельный класс, унаследованный от класса WatiN.Core.Page. В этом классе описывается мэппинг контролов страницы на определенные свойста класса с помощью атрибутов, а так же реализуется логика взаимодействия со страницей в методах класса.

Реализованные классы страниц могут быть повторно использованы во множестве тестов с разными входными данными и с разными наборами страниц.
Таким образом, при чтении теста тестировщик или разработчик концентрируется не на полях ввода и кнопках, а на бизнес-логике и логике взаимодействия с веб приложением.

Классический API можно увидеть на главной странице сайта WatiN, я же приведу пример "Page-based API":
using (var ie = new IE("http://www.google.com"))
{
var page = ie.Page<GoogleSearchPage>();
page.SearchFor("WatiN");
}
...

[Page(UrlRegex="www.google.*")]
public class GoogleSearchPage : Page
{
[FindBy(Name="btnG")]
public Button SearchButton;

[FindBy(Name="q")]
public TextField SearchCriteria;

public void SearchFor(string searchCriteria)
{
this.SearchCriteria.TypeText(searchCriteria);
this.SearchButton.Click();
}
}

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

Пример реального кода на WatiN:
browser = new IE(fedExHomePageUrl);
browser.Page<FedExLoginPage>().LogIn(login, password);
browser.GoTo(fedExSearchPageUrl);
browser.Page<FedExSearchPage>().Search(dateFrom, dateTo);
browser.Page<FedExSearchResultPage>().SaveAs(reportPath);
browser.Page<FedExDownloadPage>().Download(browser, reportPath);
...

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


WatiN даже умеет взаимодействовать со скрытым окном браузера, что позволяет запускать integration тесты на локальной машине прямо во время работы.


Стоит отметить, что в работе со скрытым окном браузера есть несколько ньюансов:

1. Если понадобится сделать скриншот страницы, то окно браузера необходимо сделать видимым, но не активным, иначе вместо скриншота у нас будет снимок черного экрана. Окно можно делать не активным, чтобы оно не мешало работе. После снятия скриншота окно можно будет сразу же спрятать:
browser.ShowWindow(NativeMethods.WindowShowStyle.ShowNormalNoActivate);
browser.CaptureWebPageToFile(debugImagePath);
browser.ShowWindow(NativeMethods.WindowShowStyle.Hide);

2. Обработка диалоговых окон часто завершается неудачей без видимых на то причин. К сожалению у меня не было достаточно времени чтобы четко вычислить закономерность поведения, поэтому я проблему решил приведением окна браузера в видимый + активный режим. Понятно что побочным эффектом будет периодические появления диалоговых окон в самый неудачный для вас момент, но как правило таких ситуаций не так уж и много. Буду очень признателен, если кто-нибудь подскажет решение данной проблемы.

3. На моем копьютере WatiN отказывается работать в режиме Windows Service без доступа к рабочему столу, несмотря на то что на официальном сайте утверждается обратное.

...случайно заметил что в IE8 все вставки кода выглядят просто ужасно. Что интересно, FF и iPhone показывают правильно.