Juniors, QA

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.

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 PagesWelcomePage.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.

Podobne artykuły

[wpdevart_facebook_comment curent_url="https://geek.justjoin.it/wzorzec-projektowy-musisz-znac-zalety-page-object-model/" order_type="social" width="100%" count_of_comments="8" ]