Page Object Model - Jak pisać stabilne i czytelne testy UI?

Schemat **page object model** pokazuje, jak test skryptu używa obiektów stron do interakcji z elementami strony, np. logowania.

Napisano przez

Eryk Pawlak

Opublikowano

12 lut 2026

Spis treści

Wzorzec page object model porządkuje testy UI tak, żeby selektory, logika interakcji i asercje nie mieszały się w każdym scenariuszu. W praktyce chodzi o to, by test opisywał zachowanie użytkownika, a nie szczegóły DOM-u. To szczególnie ważne, gdy aplikacja zmienia układ, a zespół chce utrzymać automatyzację bez ciągłego przepisywania tych samych fragmentów.

Najważniejsze zasady, które sprawiają, że POM naprawdę upraszcza testy

  • Obiekt strony ma reprezentować sensowny fragment interfejsu, a nie tylko listę selektorów.
  • Test powinien mówić, co robi użytkownik, a nie jak wygląda DOM.
  • Asercje zwykle zostają w teście, a nie w obiekcie strony.
  • Największy zysk pojawia się wtedy, gdy wiele scenariuszy używa tych samych ekranów i komponentów.
  • Nadmiar abstrakcji potrafi zepsuć czytelność szybciej niż pojedynczy powtórzony selektor.

Na czym polega wzorzec obiektów stron

Ja zwykle zaczynam od prostego pytania: czy ten test da się przeczytać jak opis działań użytkownika? Jeśli odpowiedź brzmi „nie”, to najczęściej problemem jest właśnie brak warstwy pośredniej między testem a interfejsem. Obiekt strony przejmuje wtedy odpowiedzialność za to, jak znaleźć element, kliknąć przycisk, wpisać tekst albo przejść do kolejnego ekranu.

To nie jest tylko elegancki podział kodu. Chodzi o to, żeby testy nie znały szczegółów implementacyjnych, takich jak nazwy klas CSS, kolejność pól w formularzu czy techniczny układ komponentów. Gdy zmienia się UI, poprawiasz głównie jeden plik albo kilka ściśle powiązanych klas, a nie cały zestaw scenariuszy. Dopiero wtedy widać, dlaczego samo trzymanie selektorów w jednym miejscu nie wystarcza.

W dobrze ułożonym projekcie taki obiekt reprezentuje nie całą aplikację, ale jej sensowny fragment: logowanie, koszyk, listę produktów, panel użytkownika. To ważne rozróżnienie, bo nazwa wzorca bywa myląca. Nie każda strona musi dostać osobny byt, ale każdy istotny obszar interfejsu powinien mieć własną, prostą reprezentację.

Repozytorium selektorów to za mało

Najczęstszy błąd, jaki widzę w praktyce, polega na tym, że zespół buduje zwykłe repozytorium elementów i nazywa je POM-em. To jeszcze nie rozwiązuje problemu. Samo ukrycie lokatorów jest przydatne, ale prawdziwa wartość pojawia się dopiero wtedy, gdy obiekt strony zaczyna oferować działania, a nie tylko dane techniczne.

  • Dobry obiekt strony mówi: „zaloguj użytkownika”, „wyszukaj produkt”, „otwórz koszyk”.
  • Słaby obiekt strony mówi: „znajdź input po selektorze i wpisz tekst”.
  • Dobry obiekt strony trzyma selektory w prywatnym zakresie.
  • Słaby obiekt strony zmusza test do grzebania w strukturze DOM-u.

W dokumentacji Selenium ten kierunek jest opisany bardzo jasno: testy mają być odseparowane od lokatorów i układu strony, a asercje zwykle powinny zostać po stronie testu. Ja stosuję tę zasadę niemal zawsze, bo inaczej klasa odpowiadająca za ekran szybko zamienia się w przeładowany magazyn logiki. Jedyny sensowny wyjątek to krótka weryfikacja, że strona faktycznie się załadowała i jest gotowa do pracy.

To prowadzi do ważnego wniosku: jeżeli obiekt strony nie upraszcza testu, tylko przenosi tę samą złożoność w inne miejsce, nie ma powodu, żeby go utrzymywać w tej formie. Wtedy lepiej rozdzielić odpowiedzialności jeszcze raz, zanim kod urośnie do nieczytelnego rozmiaru.

Schemat **page object model** pokazuje, jak test skrypt korzysta z obiektów stron, by interakcje były czytelne i łatwe w utrzymaniu.

Jak zbudować warstwę stron w testach UI

Najczytelniejszy model zaczyna się od podzielenia kodu na warstwy. Test ma wyrażać intencję, obiekt strony ma znać mechanikę interakcji, a komponenty mają wycinać powtarzalne fragmenty interfejsu. To prosty układ, ale tylko wtedy działa dobrze, gdy publiczny interfejs obiektu naprawdę odpowiada temu, co robi użytkownik.

Warstwa Odpowiedzialność Czego nie powinna robić
Test Opisuje scenariusz i sprawdza wynik Nie powinien znać szczegółów selektorów
Obiekt strony Ukrywa selektory i udostępnia akcje użytkownika Nie powinien zawierać logiki biznesowej
Obiekt komponentu Obsługuje powtarzalny fragment UI, na przykład nagłówek lub koszyk Nie powinien udawać pełnej strony, jeśli nią nie jest
Fixture lub helper Przygotowuje kontekst testu i dane wejściowe Nie powinien przejmować odpowiedzialności za cały ekran

Ja zwykle układam to w pięciu krokach. Najpierw identyfikuję stabilne fragmenty interfejsu, potem opisuję publiczne metody jako akcje użytkownika, następnie chowam selektory do wnętrza klasy. Kolejny krok to zwracanie nowego obiektu strony po nawigacji, a na końcu wydzielam komponenty tam, gdzie ten sam fragment pojawia się w kilku miejscach.

LoginPage
  private locators: username, password, submit

  public methods:
    enterUsername()
    enterPassword()
    submit() -> HomePage

Taki zapis jest celowo prosty. Jeśli nazwy metod zaczynają przypominać techniczne kliknięcia po DOM-ie, to zwykle znak, że API obiektu nie mówi już językiem biznesowym. Z kolei jeśli klasa robi wszystko naraz, warto rozbić ją na mniejsze elementy, zanim stanie się trudna do utrzymania.

Dokumentacja Playwright traktuje model stron jako jeden ze sposobów organizacji większych zestawów testów, co dobrze pasuje do projektów z rosnącą liczbą scenariuszy. To właśnie tam ten wzorzec zaczyna być najbardziej opłacalny, bo oszczędza czas nie przy pierwszym teście, ale przy każdym kolejnym.

Kiedy ten wzorzec daje największą przewagę

W małym projekcie różnica bywa skromna. Gdy masz kilka prostych testów, czasem szybciej jest napisać je bez dodatkowej warstwy abstrakcji. Ale przy kilkudziesięciu albo kilkuset scenariuszach sytuacja zmienia się wyraźnie: każda zmiana selektora, tekstu przycisku albo kolejności kroków zaczyna kosztować, a POM oddaje ten koszt z powrotem w postaci jednego miejsca do poprawki.

  • gdy wiele testów korzysta z tych samych ekranów;
  • gdy UI zmienia się częściej niż logika biznesowa;
  • gdy nad automatyzacją pracuje kilka osób równolegle;
  • gdy zależy Ci na czytelnych krokach testu, a nie na rozproszonych wywołaniach `findElement`;
  • gdy chcesz ograniczyć liczbę powtórzeń tych samych selektorów w całym repozytorium.

W praktyce największa przewaga pojawia się tam, gdzie zmiana frontendu jest częsta, a testy muszą nadążać bez długich przestojów. Wtedy nawet niewielka poprawka w jednym obiekcie strony potrafi oszczędzić godzinę pracy przy całej paczce scenariuszy. I właśnie dlatego ten wzorzec najlepiej oceniać nie po pierwszym dniu, ale po kilku iteracjach rozwoju aplikacji.

Gdzie zaczyna przeszkadzać

Są też sytuacje, w których rozbudowywanie tej warstwy bardziej szkodzi niż pomaga. Jeśli test jest jednorazowy, krótki albo ma jedynie potwierdzić, że krytyczny ekran się ładuje, pełna architektura obiektów stron może okazać się zwyczajnie za ciężka. Ja nie budowałbym wtedy całej platformy tylko po to, by kliknąć dwa elementy i sprawdzić jeden komunikat.

  • Krótki smoke test lepiej napisać prosto niż ubierać go w dużą abstrakcję.
  • Silnie dynamiczny interfejs czasem wymaga komponentów albo innego podziału niż klasyczna strona.
  • Przerost abstrakcji spowalnia debugowanie i utrudnia szybkie poprawki.
  • Ukryte oczekiwania i magiczne waity w obiekcie strony potrafią zamaskować prawdziwy problem.

W takich przypadkach lepsza jest prostota niż elegancja na papierze. Jeśli warstwa abstrakcji nie oszczędza czasu w utrzymaniu, nie ma sensu jej dokręcać. To szczególnie ważne w projektach, w których testy mają wspierać szybkie wydania, a nie zamieniać się w osobny, trudny do zrozumienia framework.

POM a helpery, komendy i testy bez abstrakcji

Żeby dobrze wybrać podejście, trzeba zobaczyć różnicę między kilkoma popularnymi sposobami organizacji testów. Nie każda baza kodu musi wyglądać tak samo, ale każda potrzebuje jasnej granicy między tym, co jest scenariuszem, a tym, co jest techniczną obsługą UI. Ja najczęściej wybieram obiekty stron jako środek ciężkości, a resztę dopasowuję do skali projektu.

Podejście Kiedy ma sens Największe ograniczenie
Gołe selektory w testach Mały, jednorazowy zestaw testów Szybko robi się kruchy i trudny do utrzymania
Helpery i funkcje pomocnicze Gdy chcesz wyciągnąć powtarzalne fragmenty bez pełnej abstrakcji Łatwo zamienić je w rozproszony zbiór luźnych skrótów
Obiekty stron Średnie i duże suite’y, dużo wspólnych ekranów Wymaga dyscypliny, żeby nie przeładować klas
Podejście komendowe lub DSL Gdy chcesz pisać scenariusze językiem biznesowym Więcej abstrakcji i większy koszt wejścia

Ten wybór nie jest religią, tylko kompromisem między czytelnością, kosztem zmian i tempem pracy. Jeśli zespół myli helpery z pełnym modelem stron, zwykle kończy z kodem, który wygląda na uporządkowany, ale nadal trudno go rozwijać. Z kolei dobrze użyty POM daje najlepszy balans tam, gdzie trzeba utrzymać równowagę między prostotą testu a stabilnością całej warstwy automatyzacji.

Mój filtr przed wdrożeniem w projekcie

Przed wdrożeniem tej architektury sprawdzam pięć rzeczy. To szybki filtr, który pozwala mi ocenić, czy wzorzec faktycznie pomoże, czy tylko dołoży kolejną warstwę do utrzymania.

  • Czy obiekt reprezentuje sensowny fragment interfejsu, a nie tylko zbiór przypadkowych elementów?
  • Czy publiczne metody opisują intencję użytkownika?
  • Czy selektory są ukryte wewnątrz klasy?
  • Czy asercje zostały tam, gdzie powinny, czyli w teście?
  • Czy powtarzalne fragmenty UI są wydzielone jako komponenty, zamiast dublować się w kilku klasach?

Jeśli odpowiedź na większość tych pytań brzmi „tak”, to wiem, że warstwa obiektów stron realnie pomoże zespołowi. Jeśli nie, wolę uprościć model, zanim zacznie generować dodatkowy koszt. W automatyzacji testów najlepsze rozwiązania nie są najbardziej rozbudowane, tylko takie, które naprawdę zmniejszają liczbę problemów przy kolejnych zmianach aplikacji.

FAQ - Najczęstsze pytania

POM to wzorzec projektowy porządkujący testy UI, oddzielający logikę testu od szczegółów implementacji interfejsu. Obiekty stron reprezentują fragmenty UI, ukrywając selektory i udostępniając akcje użytkownika, co zwiększa czytelność i stabilność testów.

POM sprawia, że testy są bardziej stabilne i łatwiejsze w utrzymaniu. Zmiany w UI wymagają poprawek w jednym miejscu (obiekcie strony), a nie w wielu scenariuszach testowych. Testy stają się czytelniejsze, opisując działania użytkownika, a nie techniczne detale DOM.

Repozytorium selektorów tylko ukrywa lokatory. Prawdziwy POM idzie dalej – obiekt strony oferuje konkretne *działania* użytkownika (np. "zaloguj", "wyszukaj"), a nie tylko dostęp do elementów. Oddziela to test od technicznych szczegółów interakcji z UI.

Największy zysk z POM pojawia się w średnich i dużych projektach z wieloma testami korzystającymi z tych samych ekranów. Jest nieoceniony, gdy UI często się zmienia, nad automatyzacją pracuje wiele osób, a czytelność i stabilność testów są kluczowe.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi:

page object model jak zaimplementować page object model page object model w testach automatycznych zalety page object model kiedy stosować page object model

Udostępnij artykuł

Eryk Pawlak

Eryk Pawlak

Jestem Eryk Pawlak, doświadczony analityk branżowy z wieloletnim zaangażowaniem w tematykę technologii. Od ponad pięciu lat zajmuję się analizowaniem trendów rynkowych oraz innowacji technologicznych, co pozwoliło mi zdobyć głęboką wiedzę na temat rozwoju różnych sektorów. Moja specjalizacja obejmuje zarówno nowe technologie, jak i ich wpływ na codzienne życie oraz przemysł. Stawiam na obiektywną analizę i rzetelne badania, co pozwala mi na uproszczenie skomplikowanych danych dla moich czytelników. Wierzę, że kluczowe jest dostarczanie aktualnych informacji w przystępny sposób, aby każdy mógł zrozumieć dynamicznie zmieniający się świat technologii. Moim celem jest zapewnienie wiarygodnych i wartościowych treści, które pomagają w podejmowaniu świadomych decyzji.

Napisz komentarz