Ten wzorzec projektowy musisz znać. Zalety Page Object Model
Wzorzec projektowy Page Object jest obecnie jednym z najpopularniejszych podejść do automatyzacji testów webowych. Znajduje zastosowanie we frameworkach tworzonych według paradygmatu programowania obiektowego i pozwala na pełne wykorzystanie jego zalet. Na czym polega Page Object i w czym dokładnie może pomóc?
Agata Ostaszewska-Smykała. Product Engineer w Axxiome Polska, związana z branżą IT i testowaniem oprogramowania od prawie siedmiu lat. Absolwentka informatyki, studentka filologii angielskiej, wolny czas poświęca literaturze i nauce języków obcych, a także rozwojowi umiejętności programowania w Javie. Od niedawna prowadzi bloga znerdziej.pl, skierowanego przede wszystkim do osób rozpoczynających karierę w IT.
Najważniejszą ideą, stojącą u podstaw wzorca Page Object, jest opakowanie strony i jej elementów w odpowiednie klasy i ich pola. Należy pamiętać, że wbrew temu, co sugeruje powszechnie przyjęte nazewnictwo, klasą niekoniecznie musi być cała strona – w praktyce częściej zdarza się, że jest nią określona funkcjonalna część strony, na przykład panel czy lista wyników wyszukiwania. Elementy strony zaczynają odpowiadać polom klasy, a czynności, które można za ich pomocą wykonać wykonać – metodom tej klasy. Powstaje w ten sposób swojego rodzaju API (interfejs aplikacji), umożliwiający testom wykonywanie czynności na stronie bez odwoływania się do ścieżek do elementów. Upraszcza to prace nad automatyzacją i poprawia czytelność samych metod testowych.
Spis treści
Architektura
W typowym przypadku kod rozdzielony jest na klasy opakowujące testowane strony (przykładowo zgromadzone w folderze o nazwie Pages) i na scenariusze testowe (znajdujące się na przykład w folderze Tests). Testy korzystają z obiektów klas z folderu Pages, aby wykonywać poszczególne kroki na stronie. Jeżeli chodzi o asercje, można znaleźć zarówno zwolenników umieszczania ich w testach, jak i w klasach stron. Zwolennicy obu rozwiązań mają swoje argumenty, jednak najważniejsze wydaje się, aby konsekwentnie trzymać się wybranej opcji i nie mieszać dwóch podejść.
Do znajdowania elementów na stronie wykorzystuje się koncepcję o nazwie Page Factory. Polega ona na zadeklarowaniu obiektów typu WebElement, a następnie oznaczeniu ich adnotacją @FindBy wraz ze ścieżką szukanych elementów (przykładowo w postaci xPath czy ścieżki CSS). Elementy te następnie inicjalizuje się poprzez wywołanie statycznej metody initElements klasy PageFactory, dostępnej jako część biblioteki WebDrivera. Metodę tę wywołuje się w konstruktorze klasy. Być może brzmi to skomplikowanie, jednak prosty przykład powinien wszystko wyjaśnić.
Przykład
Załóżmy, że istnieje strona logowania, składająca się z trzech elementów – pola tekstowego przyjmującego nazwę użytkownika, pola tekstowego przyjmującego hasło i przycisku „Zaloguj”. Przy tak prostej stronie wydaje się zasadne, aby cała strona odpowiadała jednemu obiektowi. Tworzymy zatem folder Pages, a w nim LoginPage.java:
public class LoginPage{ WebDriver driver; //konstruktor public LoginPage(WebDriver driver){ this.driver = driver; } }
Na początek deklarujemy w klasie elementy strony, korzystając z PageFactory (w przykładzie pokazano różne sposoby wyszukiwania elementów – w praktyce dałoby się to uprościć):
@FindBy(xpath=” //*[@id="username"]”) WebElement usernameInput; @FindBy(id=”pass”) WebElement passwordInput; @FindBy(className=”submitBtn”) WebElement loginButton;
Do konstruktora dodajemy inicjalizację elementów, przez co wygląda on teraz następująco:
public LoginPage(WebDriver driver){ this.driver = driver; PageFactory.initElements(driver, this); }
Pozostaje już tylko napisać metody umożliwiające wykonywanie czynności za pomocą elementów strony:
public void enterUsername(String username){ usernameInput.sendKeys(username); } public void enterPassword(String password){ passwordInput.sendKeys(password); } public void login(){ loginButton.click(); }
Aby przeprowadzić weryfikację logowania, potrzebny będzie obiekt strony, która otworzy się po poprawnym zalogowaniu. Tworzymy więc kolejną klasę w folderze Pages – WelcomePage.java. Przykładowo mogłaby ona wyświetlać powitalny tekst „Welcome” i nazwę zalogowanego użytkownika oraz udostępniać przycisk wylogowania. Klasa dla takiej strony wyglądałaby następująco:
public class WelcomePage{ WebDriver driver; @FindBy(id=”welcomeTxt”) WebElement welcomeText; @FindBy(id=”loggedUser”) WebElement loggedUser; @FindBy(id=”logoutBtn”) WebElement logoutButton; public WelcomePage(WebDriver driver){ this.driver = driver; PageFactory.initElements(driver, this); } public String getWelcomeTxt(){ return welcomeText.getText(); } public String getLoggedUser(){ return loggedUser.getText(); } public void logout(){ logoutButton.click(); } }
Kiedy klasy stron są gotowe, przechodzimy do pisania testu – dodajemy plik US01.java w folderze Tests:
public class US01 { WebDriver driver; @Before public void setup(){ //ustawienia drivera i przejście do naszej strony logowania } @Test() public void correctLogin(){ String correctUsername = “correctusername”; String correctPassword = “correctpass1”; Loginpage loginPage = new LoginPage(driver); loginPage.enterUsername(correctUsername); loginPage.enterPassword(correctPassword); loginPage.login(); WelcomePage welcomePage = new WelcomePage(driver); Assert.assertTrue(welcomePage.getWelcomeText() .contains(“Welcome”)); Assert.assertTrue(welcomePage.getLoggedUser() .contains(correctUsername); } }
Podsumowanie
Page Object Model pozwala na wykorzystanie zalet programowania obiektowego podczas implementacji testów automatycznych. Kod klas reprezentujących strony może zostać wielokrotnie wykorzystany w różnych testach, natomiast same scenariusze stają się czytelne dzięki temu, że składają się z wywołania metod odpowiadających poszczególnym krokom. Uproszczone jest również utrzymanie takich testów – w razie gdyby ścieżka do elementu została zmieniona, potrzebna będzie jej aktualizacja jedynie w klasie reprezentującej stronę. Podobnie w przypadku zmiany sposobu wykonywania danej czynności na stronie – wystarczy zaktualizować odpowiadającą jej metodę, bez konieczności modyfikacji wszystkich korzystających z niej testów.
Zdjęcie główne artykułu pochodzi z pexels.com.