Wzorzec Page Object jest obecnie jednym z najczęściej stosowanych przy tworzeniu testów aplikacji webowych. Pozwala na odwzorowanie stron internetowych w klasy, w których metody reprezentują możliwe do wykonania akcje, natomiast pola - elementy na stronie. Takie podejście umożliwia oddzielenie logiki testu od kodu odpowiedzialnego za interakcję z przeglądarką (np. wyszukiwanie elementów). Pisane w ten sposób testy stają się więc czytelniejsze oraz łatwiejsze w utrzymaniu, gdyż zmiana na stronie nie wymusza aktualizacji wielu testów, a jedynie pojedyncze klasy.
Stosowanie powyższego wzorca może zatem przynieść wiele korzyści, jednakże sposób jego implementacji jest również istotny. Przykładowo wraz ze wzrostem liczby testowanych stron może wzrosnąć liczba klas im odpowiadającym, a tym samym koszt utrzymania całej solucji testowej.
WebAutomation pozwala na uproszczenie procesu tworzenia klas (odpowiadającym stronom) poprzez ich automatyczne generowanie na podstawie pliku XML. W ten sposób zmniejsza się nakład pracy potrzebny na ich ręczne tworzenie oraz upraszcza się proces zarządzania nimi.
W pliku XML strony opisuje są za pomocą struktury hierarchicznej, co przekłada się na dziedziczenie w wygenerowanych klasach. Elementy zdefiniowane w klasach nadrzędnych są więc dostępne w klasach dziedziczących. Jest to szczególnie przydatne, gdy dana strona zawiera elementy wspólne występujące na wielu podstronach, np. menu główne, przyciski, itp.
Przykładowy plik XML dla serwisu youtube.com (utworzenie trzech stron, z których dwie dziedziczą po YoutubePage):
<container name="YoutubePage">
<component name="SearchInput" id="masthead-search-term" />
<component name="OkButton" xpath="//*[@id='search-btn']/span" />
<container name="YoutubeSearchResultPage">
<component name="Link" pxpath="//a[@title='{0}']" />
</container>
<container name="YoutubePlayerPage">
<component name="Player" id="player-api" />
</container>
</container>
Sposób wyszukiwania elementów na stronie określa się w XML-u poprzez zdefiniowanie odpowiednich atrybutów, np. "id", "xpath", "class", itp. Pozwalają one na automatyczne znajdywanie elementów bez konieczności odwoływania się do WebDrivera.
W przypadku, gdy dany element nie posiada stałej wartości (np. jego wartość zależy od wpisów w bazie danych), można skorzystać z tzw. sparametryzowanych atrybutów, np. "pid", "pxpath", "pclass". Atrybuty te posiadają parametry ("{0}", "{1}", itd.), do których wartości będą przekazywane w trakcie trwania testu. Dzięki temu możliwe jest utworzenie pliku XML niezależnego od danych testowych, gdzie elementy będą reużywalne (zależnie od logiki testu). Przykładowe zastosowanie atrybutu "pxpath" można zaobserwować w powyższym przykładzie dla elementu "Link" na stronie "YoutubeSearchResultPage".
Aby skorzystać z klas wygenerowanych na podstawie pliku XML, należy uruchomić skrypt T4 dostarczony wraz z frameworkiem. Następnie należy utworzyć test dziedziczący po klasie bazowej "TestBase" i w metodzie testowej pobrać stronę za pomocą "GetContainer<PageType>()". Po tej operacji mamy dostęp do wszystkich elementów zdefiniowanych na stronie oraz metod pomocniczych, które na nich operują.
Przykładowy kod testu dla powyższego pliku XML:
[TestFixture]
public class YoutubeTests : TestBase
{
[Test]
public void OpenVideo()
{
this.WebDriver = new FirefoxDriver();
this.WebDriver.Navigate().GoToUrl("https://www.youtube.com");
var youtubePage = this.GetContainer<YoutubePage>();
youtubePage.SearchInput.Perform.Fill("Hans Zimmer greatest hits");
youtubePage.OkButton.Perform.Click();
var searchResultsPage = this.GetContainer<YoutubeSearchResultPage>();
searchResultsPage.Link.With("The greatest hits from Hans Zimmer").Perform.Click();
var playerPage = this.GetContainer<YoutubePlayerPage>();
playerPage.Player.Assert.Is.Displayed();
this.QuitBrowser();
}
}
Jak widać na powyższym przykładzie, WebAutomation pozwala w prosty sposób korzystać z wygenerowanych klas oraz ich elementów. Co więcej, zawiera zestaw metod opakowujących domyślne działanie Selenium, oferując przy tym:
- automatyczne wyszukiwanie elementów (zarówno statycznych, jak i tych o zmiennej wartości),
- gotowe metody do asercji (również z obsługą czekania na element pojawiający się po chwili),
- czytelny zapis operacji (w jednym ciągu wywołań można pobrać element, przekazać opcjonalne parametry, wykonać akcję/asercję),
- szczegółowe logi z wykonania testu (szczególnie przydatne przy analizie raportów testowych),
- możliwość tworzenia własnych rozszerzeń (np. własne atrybuty w XML-u).
Powyższy opis biblioteki nie opisuje wszystkich jej możliwości, dlatego w celu uzyskania szczegółowych informacji zachęcam do odwiedzenia poniższych stron.
Paczka z najnowszą wersją:
https://www.nuget.org/packages/WebAutomation
Strona główna projektu (repozytorium + dokumentacja):
https://bitbucket.org/mk_meros/webautomation/wiki/Home
Repozytorium z przykładami:
https://bitbucket.org/mk_meros/webautomation-samples
Autor: Marek Kudliński
Inżynier jakości z prawie 5-letnim stażem, pasjonat testów automatycznych, finalista TestingCup 2015.
Marek jest autorem frameworka i udostępnił go na licencji MIT license.