Sii Polska

SII UKRAINE

SII SWEDEN

  • Szkolenia
  • Kariera
Dołącz do nas Kontakt
Wstecz

Sii Polska

SII UKRAINE

SII SWEDEN

Wstecz

13.12.2024

Playwright w praktyce: 5 kroków do skutecznego frameworka do automatyzacji testów UI & Web. Część I

13.12.2024

Playwright w praktyce: 5 kroków do skutecznego frameworka do automatyzacji testów UI & Web. Część I

Tym artykułem chciałbym rozpocząć serię wpisów, w której pokażę, jak krok po kroku zbudować nowoczesny framework do automatyzacji testów, korzystając z Playwrighta oraz TypeScripta.

Istnieją różne opinie na temat tego, czy właściwszym określeniem jest „framework testowy”, czy „biblioteka testowa”. Niemniej, przyjmuję, że na potrzeby tej serii artykułów używamy terminu „framework testowy”.

Jakiś czas temu opublikowałem wpis, w którym opisałem, jak rozpocząć swoją przygodę z Playwrightem. Również dwa inne artykuły na temat Playwrighta pojawiły się na blogu Sii nieco później.

Dziś pójdziemy o krok dalej. Skupimy się na tym, jak stworzyć bardziej zaawansowane rozwiązanie – takie, które będziecie mogli zastosować w swojej codziennej pracy.

Na początek warto zastanowić się nad wyborem odpowiedniego języka programowania. Przyjrzymy się i porównamy różne opcje, aby wybrać najlepsze narzędzie do realizacji naszych celów.

  1. Popularność rozwiązania – dlaczego TypeScript?
  2. Czym powinien charakteryzować się framework testowy?
  3. Wzorce projektowe i dobre praktyki
  4. Raportowanie
  5. CI / CD

Temat podzielę na dwie części – w pierwszej skupię się trochę bardziej na teorii i podkreśleniu, które obszary są ważne, zaś w kolejnej pokażę kod i omówię go krok po kroku. Całość kodu będzie dostępna wraz z drugim wpisem.

Kod

Nasz framework testowy będzie zawierał dwa przykłady testów, które będą możliwe do pobrania z GitHub Sii Poland.

Do stworzenia testów skorzystam z Trello.

Trello – aplikacja do zarządzania projektami
Ryc. 1 Trello – aplikacja do zarządzania projektami

Trello to aplikacja służąca do zarządzania projektami z wykorzystaniem metodologii Kanban. Jest to zaawansowane narzędzie zarówno pod względem interfejsu użytkownika (UI), jak i możliwości API. Z naszej perspektywy stanowi doskonałe środowisko do ćwiczenia umiejętności związanych z automatyzacją procesów.

Do celów testowych zachęcamy do założenia konta – bezpłatny plan jest w zupełności wystarczający.

Dlaczego TypeScript?

TypeScript to popularny język programowania, od lat wykorzystywany głównie do tworzenia front-endu w aplikacjach webowych. Istnieje kilka powodów, dla których TypeScript doskonale sprawdza się jako język dla frameworków testowych.

Oto najważniejsze argumenty:

  1. Silne typowanie – umożliwia wykrywanie błędów na etapie kompilacji, co zwiększa stabilność kodu.
  2. Lepsza współpraca z Playwright API – Playwright w połączeniu z TypeScriptem oferuje największą liczbę usprawnień i nowych funkcji w porównaniu do innych implementacji.
  3. Wbudowane wsparcie dla async/await – ułatwia tworzenie stabilnych i czytelnych testów automatycznych.
  4. Popularność i wsparcie społeczności – dzięki dużej społeczności łatwo znaleźć odpowiedzi na pytania, a sam Playwright został stworzony w TypeScript.

Warto dodać, że mimo zalet TypeScriptu, Playwright można używać także w innych językach programowania, takich jak C# czy Java. Sam z powodzeniem korzystałem z tych implementacji w codziennej pracy i również się sprawdzały.

Dla osób, które nie planują korzystać z TypeScriptu, artykuł nadal może okazać się wartościowy, ponieważ koncepcje związane z tworzeniem testowego frameworka są spójne niezależnie od technologii.

Popularność rozwiązania – TypeScript a inne język programowania

Gdy pisałem artykuł Playwright – dlaczego warto zainteresować się narzędziem od Microsoftu?, Playwright powoli stawał się coraz popularniejszym rozwiązaniem do automatyzacji testów. Obecnie przejął prowadzenie nad Cypressem i Selenium w ilości pobrań miesięcznych. Również w ofertach pracy można zauważyć, że liczba ofert, w których Playwright jest/bywa wymagany, rośnie.

Liczba pobrań Cypress, Playwright i Selenium w ostatnim roku
Ryc. 2 Liczba pobrań Cypress, Playwright i Selenium w ostatnim roku

Warto podkreślić, że nie twierdzę, iż Selenium czy Cypress to złe narzędzia. Korzystałem z obu w różnych projektach i uważam, że przy odpowiednim doświadczeniu osoby piszącej testy można osiągnąć bardzo dobre rezultaty w obu przypadkach.

To, co przyciąga mnie do Playwright i dlaczego tak chętnie o nim piszę oraz tworzę prezentacje, to fakt, że narzędzie wyróżnia się dynamicznym rozwojem i oferuje kilka rozwiązań, które uważam za bardziej efektywne.

Warto jednak obserwować rozwój innych narzędzi, takich jak Selenium, gdzie od jakiegoś czasu prowadzone są intensywne prace. Może to sprawić, że w przyszłości Selenium stanie się jeszcze bardziej popularnym i nowoczesnym rozwiązaniem. Trzeba również zaznaczyć, że większość konceptów dla testów API czy UI jest podobnych, więc nawet jeśli nie korzystasz z Playwrighta, ten artykuł może być przydatny dla Ciebie.

Czym powinien charakteryzować się framework testowy?

Framework testowy powinien pozwalać tworzyć rozwiązania łatwo utrzymywane oraz wspierać kilka obszarów:

  • Wzorce projektowe i dobre praktyki – w naszym rozwiązaniu musimy uwzględnić użycie praktyk, które pozwolą nam na łatwe rozwijanie narzędzia i jego utrzymywanie.
  • Współbieżność – poza dbaniem o wzrost pokrycia testami, równie ważnym aspektem jest zadbanie o to, żeby testy uruchamiały się najszybciej jak to możliwe.
  • Raportowanie wyników testów – wdrożenie efektywnego sposobu raportowania wyników z testów. O Raportowaniu w Playwright napisałem artykuł.
  • CI/CD –  nawet najlepszy framework testowy, jeśli nie jest zintegrowany z naszymi narzędziami CI/CD, staje się istotnym problem całego rozwiązania.

Warto też zwrócić uwagę na piramidę testów, w taki sposób, aby nie mieć ogromnej ilości testów UI, tylko starać się przenosić te testy do niższej warstwy, jeżeli jest to możliwe. Oczywiście dużo zależy od architektury aplikacji. W sytuacji, gdy tworzymy testy dla aplikacji składającej się z mirkoserwisów, prawdopodobnie przede wszystkim lepszym wyjście będzie skupienie się na testach integracyjnych/kontraktowych.

Piramida testów
Ryc. 3 Piramida testów

Widziałem różne implementacje piramidy testów – ważne jest, aby dążyć do umieszczania testów funkcjonalnych na niższych poziomach piramidy. Dzięki temu stają się one stabilniejsze i szybciej się wykonują.

Wzorce projektowe i dobre praktyki

Framework testowy powinien wspierać wzorce projektowe stosowane w naszym rozwiązaniu. Oznacza to, że ma być wystarczająco elastyczny, aby umożliwiać korzystanie z dobrych praktyk. Playwright spełnia te wymagania, dlatego przedstawię kilka praktyk, które mogą pomóc w stworzeniu rozwiązania łatwego w utrzymaniu oraz sprzyjającego przyjemnemu i efektywnemu tworzeniu kolejnych testów.

Zacznijmy od omówienia Fixtures!

Fixtures

Jest to przydatny mechanizm znany w świecie TypeScript/JavaScript, który umożliwia tworzenie części kodu wielokrotnego użytku w różnych obszarach testów. Mechanizm ten świetnie sprawdza się w przypadku obiektów typu Page Object lub innych elementów, które chcemy zainicjalizować w jednym miejscu i wykorzystywać w wielu miejscach, na przykład w kodzie testów.

Zalety podejścia:

  • możliwość wielokrotnego wykorzystania danych,
  • zwiększona czytelność,
  • zwiększona czytelność.

Wady podejścia:

  • narzut spowodowany utrzymywaniem koncepcji,
  • potencjalne zbyt duże klasy, które zawierają zbyt wiele inicjalizacji obiektów.

Jak to działa w praktyce?

W poniższym kodzie znajdziemy kilka elementów wymaganych w różnych testach. Przykładem jest klasa LoginTrelloPage, która reprezentuje Page Object. Jest ona wykorzystywana w wielu testach, w których konieczne jest logowanie do aplikacji.

kod

W naszym kodzie typ TrelloFixtures będzie zawierał dodatkowe definicje elementów, które będą wielokrotnie używane. Przykładem jest obiekt strony TrelloLoginPage przyjmujący jako parametr obiekt page. Obiekt ten jest odpowiedzialny za interakcję z daną stroną w Playwright. Dodatkowo, type Settings pozwala na przekazywanie niezbędnych wartości konfiguracyjnych. Warto zwrócić uwagę na fakt, że poza inicjalizacją obiektu, możliwe jest także wykonywanie akcji, takich jak await page.goto, która umożliwia przejście do strony powiązanej z danym obiektem strony.

kod

Page Object Pattern

Czym jest Page Object Pattern? Jak zapewne wiecie, jest to popularny wzorzec projektowy rozpropagowany przez Martina Fowlera, znanego programistę związanego z firmą ThoughtWorks. To właśnie on stoi także za innym znanym konceptem, jakim jest Piramida Testów.

Page Object Pattern polega na tworzeniu klasy powiązanej z konkretną stroną aplikacji, która zawiera zdefiniowane elementy oraz akcje związane z tą stroną. Dzięki temu uzyskujemy czytelny kod ułatwiający utrzymanie testów.

Oczywiście istnieje wiele różnych implementacji tego wzorca, jednak z mojej perspektywy kluczowe jest rozpoczęcie od przekazania świeżego obiektu, który odpowiada za kontrolowanie akcji w danym oknie przeglądarki. W świecie Playwright takim obiektem jest page.

Obiekt page reprezentuje pojedynczą stronę w przeglądarce i umożliwia interakcję z jej elementami. Dla osób, które nie znają Playwrighta, może to być mniej intuicyjne, ale w praktyce jest to niezwykle efektywne rozwiązanie.

kod

Idąc dalej w naszym przykładzie, jakim jest TrelloLoginPage, naturalną metodą będzie login, umożliwiająca zalogowanie się do aplikacji. Selectory warto przechowywać jako pola klasy, na przykład loginButtonSelector, co ułatwia ich utrzymanie i ponowne wykorzystanie. Dodatkowo metoda getAllBoardVisibleStatus() mogłaby zwracać status widoczności elementu reprezentującego wszystkie „boards” dostępne po zalogowaniu.

Factory Pattern

kod

Z mojej perspektywy, w kontekście tworzenia rozwiązań dla testów automatycznych, ten wzorzec może się sprawdzić. Oczywiście istnieją bardziej zaawansowane zastosowania, jednak zbyt złożona abstrakcja może prowadzić do dodatkowych problemów.

W naszych przykładach załóżmy, że tworzymy dwie klasy typu Factory:

  • pierwszą dla obiektów typu Card, czyli FactoryCard, która będzie zawierać metodę do tworzenia określonej karty w Trello,
  • drugą – BoardFactor, odpowiedzialną za tworzenie boardu w Trello.

Zalety podejścia:

  • reużywalność kodu i standaryzacja,
  • możliwość tworzenia różnych wariantów naszych obiektów,
  • łatwiejsze utrzymywanie kodu i refaktoryzacja danych testowych,
  • oddzielenie logiki tworzenia obiektów od testów.

Wady podejścia:

  • potencjalnie skomplikowany kod,
  • dodatkowa warstwa abstrakcji – potencjalnie może wprowadzić to trudniejsze zrozumienie kodu.

Parallelism – uruchamianie testów współbieżnie

Jednym z kluczowych aspektów, o których warto pamiętać podczas tworzenia frameworka do testów automatycznych, jest wybór narzędzia umożliwiającego współbieżne uruchamianie testów.

Czym właściwie jest współbieżne uruchamianie testów? To proces, w którym zamiast korzystać z jednego wątku, testy są wykonywane równolegle w wielu wątkach, co znacząco skraca czas ich realizacji. Uważam, że jest to jeden z najistotniejszych elementów pracy testera automatyzującego. Samo dodawanie kolejnych testów niewiele wnosi, jeśli ich uruchamianie zajmuje wiele godzin lub nawet dni. Skupienie się na tym aspekcie może znacznie przyspieszyć dostarczanie rozwiązań.

Przykładem może być jeden z projektów, w którym wraz z zespołem wdrożyliśmy Playwrighta w połączeniu z C#. Przy liczbie około 150 dość skomplikowanych testów UI & API, ich czas uruchomienia na czterech wątkach wynosił zaledwie 8 minut, czyli stosunkowo krótko. Gdybyśmy zwiększyli ilość wątków, ten czas mógłby być jeszcze bardziej satysfakcjonujący.

Możliwość korzystania z parallelismu w Playwright

Sam temat wykorzystania współbieżności mógłby być tematem osobnego artykułu lub publikacji, jednak postaram się na kilku przykładach przedstawić, jakie możliwości oferuje Playwright w tym zakresie.

Pierwszą istotną rzeczą jest szeroki wachlarz opcji dotyczących sposobu wykorzystania współbieżności. Możemy na przykład uruchamiać wszystkie testy współbieżne lub niektóre z nich. Warto przygotować rozwiązanie, tak żeby wszystkie testy były uruchamiane współbieżnie.  Takie podejście jest szczególnie polecane, ponieważ najlepiej unikać wyjątków i dostosować testy w taki sposób, aby wszystkie mogły działać współbieżnie, co zwiększa efektywność i skraca czas wykonania testów.

kod

Gdy ustawimy w pliku playwright.config.tsopcję fullyParallel na „true”, to automatycznie wszystkie testy będą się uruchamiały współbieżnie. To, co jest również ciekawe – jeżeli mamy zdefiniowaną więcej niż jedną przeglądarkę, np. korzystamy z chromium i firefoxa, to na obu przeglądarkach owe testy uruchomią się w sposób współbieżny.

Parallel w klasie

W Playwright istnieje również możliwość zdefiniowania współbieżności na poziomie klasy testowej – czy dana klasa ma korzystać ze współbieżności, czy nie. Moim zdaniem lepiej jednak zainwestować czas, aby zapewnić poprawne działanie testów w środowisku współbieżnym, zamiast tworzyć obejścia (tzw. workarounds). Dzięki temu unikniemy sytuacji, w której część testów działa współbieżnie, a inne nie, co z kolei poprawi spójność i utrzymanie całej bazy testowej.

kod

Sharding

Jednym z interesujących mechanizmów oferowanych przez Playwright jest tzw. Sharding. Mechanizm ten, zwany również fragmentacją lub podziałem, pozwala na rozdzielenie testów automatycznych na mniejsze części (np. cztery fragmenty) i ich równoległe uruchamianie w osobnych zadaniach (jobach) w systemie CI.

Sharding okazuje się szczególnie przydatny, gdy nie planujemy korzystać z bardziej zaawansowanych narzędzi (takich jak Moon), czy platform do testów w chmurze (takich jak np.:,  BrowserStack, SauceLabs czy LambdaTest lub inne). Dzięki uruchamianiu testów w podzielonej formie na wielu jobach możemy znacząco skrócić całkowity czas wykonania testów automatycznych, co pozytywnie wpływa na efektywność procesu.

Dodatkowym atutem tego rozwiązania jest możliwość integracji wyników testów. Standardowo wyniki są generowane oddzielnie dla każdego zadania (joba), jednak można je scalić w jeden zbiorczy raport. Taki raport znacząco ułatwia analizę wyników i monitorowanie efektów przeprowadzonych testów, zapewniając spójny obraz jakości aplikacji.

kod
kod

Asercje – jak podejść do asercji w naszym rozwiązaniu?

Podejście do asercji w testach może być różnorodne i jest szeroko opisywane w literaturze oraz publikacjach. Moim zdaniem kluczowe jest, aby klasa Page Object nie zawierała asercji, lecz jedynie umożliwiała zwracanie stanu danego obiektu. Na przykład: zamiast wykonywać asercję w klasie, powinna ona zwracać stan widoczności elementu, pozostawiając samą weryfikację do wykonania w kodzie testu.

Istnieją jednak sytuacje, w których trudno jest zwrócić stan elementu wprost, na przykład, gdy należy sprawdzić kilka pól jednego obiektu (jak właściwości produktu dodanego do koszyka w sklepie internetowym). W takich przypadkach można zmapować wszystkie wartości obiektu na odpowiednie pola i zapisać je w dedykowanym obiekcie. Dzięki temu klasa Page Object może zwrócić taki obiekt, a weryfikacja poprawności odbywa się w kodzie testu poprzez porównanie obiektu pobranego ze strony z wcześniej zdefiniowanym obiektem referencyjnym.

Alternatywnym rozwiązaniem jest utworzenie dedykowanej klasy zawierającej metody do bardziej zaawansowanego sprawdzania poprawności. Przykład takiego podejścia znajduje się poniżej. Należy jednak pamiętać o potencjalnych ryzykach związanych z tym podejściem – na przykład, jeśli nazwa metody w tej klasie będzie błędna, może to prowadzić do trudnych do wykrycia błędów. Dlatego istotne jest zachowanie ostrożności i odpowiedniej dbałości o szczegóły przy implementacji takich rozwiązań.

VerifyElementsInCart(cardTitles: string[], columnName: string)

kod

Tak naprawdę nie wiemy, co dokładnie sprawdza ta metoda, a dodatkowo istnieje ryzyko, że w przyszłości ktoś zmieni jej implementację, przez co przestanie ona weryfikować to, co pierwotnie zakładaliśmy. Oczywiście zmiana nazwy metody może ułatwić zrozumienie kontekstu tego, co oznacza „Verify”. Z drugiej strony – dla wielu osób jest jasne, że ta metoda sprawdza po prostu, czy „Cards” znajdują się w określonej kolumnie.

Warto jednak być precyzyjnym, aby uniknąć potencjalnych problemów. Jeśli dokładnie wiemy, co dana metoda powinna robić, możemy umieścić w niej właściwe asercje sprawdzające zawartość koszyka. Alternatywnie – można zastosować podejście, w którym metoda zwraca określony stan, a asercje dokonywane są dopiero w samym teście. Dzięki temu kod testowy pozostaje czytelny, a logika sprawdzania jasna i scentralizowana.

kod

Bazując na tym podejściu, mamy odseparowany element sprawdzenia określonej rzeczy/stanu/elementu z page objectem.

Soft Assertions

kod

Jest to również interesujący sposób na wprowadzenie asercji do kodu w taki sposób, by sprawdzenie było wykonywane podczas testu, ale jednocześnie nie powodowało jego natychmiastowego zakończenia błędem.

Podsumowanie

W tej części artykułu przedstawiłem kilka kluczowych aspektów tworzenia frameworka do testów UI i API w Playwright.

Ze względu na szeroki zakres tematu skupiłem się na omówieniu: wybranych wzorców projektowych, znaczenia współbieżności oraz podejścia do asercji. Przedstawiłem różne strategie i rozwiązania, a także wyjaśniłem, dlaczego współbieżność jest kluczowym czynnikiem umożliwiającym szybkie uzyskanie informacji zwrotnej z testów w obecnych, wymagających realiach.

W kolejnych częściach rozwinę temat danych testowych oraz pokażę, jak wygląda pełny test w praktyce.

***

Jeśli interesuje Cię tematyka Playwrighta, zajrzyj koniecznie również do innych artykułów naszych ekspertów.

5/5
Ocena
5/5
Avatar

O autorze

Michał Ślęzak

Test Architect w Sii Polska. Automatyzacją testów zajmuje się od kilku lat. Prowadzi bloga: testingplus.me oraz jest jednym z liderów PTaQ.org i prowadzącym podcastu TestingParrot: jednego z pierwszych podcastów o testowaniu w Polsce. Pisał dla geek.justjoin.it / blog.testuj.pl / Programista Magazyn. Poza pracą lubi rozwój osobisty, czytanie książek i oglądanie seriali.

Wszystkie artykuły autora

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Może Cię również zainteresować

Dołącz do nas

Sprawdź oferty pracy

Pokaż wyniki
Dołącz do nas Kontakt

This content is available only in one language version.
You will be redirected to home page.

Are you sure you want to leave this page?