Przejdź do treści
Open source i projekty społecznościowe

Cypress czy Playwright? Porównanie narzędzi open source do testów E2E w 2025 roku

Rate this post

Cypress czy Playwright: wybór zależy od sposobu pracy zespołu, nie od popularności narzędzia

Decyzja między Cypress a Playwright rzadko sprowadza się do pytania: „które narzędzie jest lepsze?”. Oba projekty open source służą do automatyzacji testów aplikacji webowych, oba pozwalają odtworzyć działania użytkownika w przeglądarce i oba dobrze pasują do nowoczesnych procesów CI/CD. Różnica polega na tym, że prowadzą zespół przez testowanie trochę inną drogą. [1]

Test end-to-end, nazywany też testem E2E, sprawdza kompletny scenariusz z perspektywy osoby korzystającej z produktu. Może obejmować logowanie, wyszukanie produktu, dodanie go do koszyka, przejście do płatności, zapis formularza albo nadanie uprawnień w panelu administracyjnym. Test nie pyta wyłącznie, czy pojedynczy komponent renderuje się poprawnie. Sprawdza, czy wiele warstw aplikacji współpracuje ze sobą w realnym przepływie.

Cypress zwykle dobrze trafia w potrzeby zespołów frontendowych pracujących głównie w JavaScripcie lub TypeScripcie, które chcą szybko tworzyć czytelne testy i obserwować ich przebieg w rozbudowanym interfejsie. Playwright jest często wybierany tam, gdzie istotne są testy wieloprzeglądarkowe, duża równoległość wykonania, izolacja scenariuszy oraz możliwość użycia kilku języków programowania.

Popularność repozytorium, liczba przykładów w internecie czy krótki fragment kodu z dokumentacji nie powinny przesądzać o wyborze. Narzędzie może wyglądać świetnie w prostym teście formularza, a jednocześnie wymagać dodatkowej pracy przy logowaniu przez zewnętrznego dostawcę tożsamości, testach wielu domen, aplikacji osadzonej w iframe albo równoległym wykonywaniu setek przypadków w pipeline CI.

Trzy sytuacje, trzy sensowne odpowiedzi

W nowym projekcie zespół ma największą swobodę. Może wybrać Playwright, jeśli od pierwszego dnia chce testować Chromium, Firefox i WebKit oraz budować szybki zestaw testów działający równolegle w CI. Może też świadomie postawić na Cypress, gdy skład zespołu jest silnie frontendowy, a najważniejsza jest prosta ścieżka wejścia oraz wygodne diagnozowanie błędów w lokalnym środowisku.

W istniejącym projekcie odpowiedź zależy od tego, co już działa. Dobrze utrzymywany zestaw testów Cypress nie staje się zły tylko dlatego, że Playwright zyskuje popularność. Migracja ma uzasadnienie wtedy, gdy obecne ograniczenia narzędzia faktycznie blokują rozwój: na przykład zespół potrzebuje testów WebKit, sprawniejszej obsługi wielu kart i domen albo bardziej efektywnego uruchamiania dużej liczby scenariuszy.

W większej organizacji ważne stają się również standardy, obsługa artefaktów z CI, bezpieczeństwo zależności open source oraz koszt utrzymania. Narzędzie wybrane przez jeden zespół może później zostać przyjęte przez kilka produktów. Wtedy liczy się nie tylko wygoda autora testu, lecz także to, czy nowe osoby zrozumieją strukturę repozytorium, czy błędy będzie można sprawnie analizować po awarii pipeline’u i czy aktualizacje zależności da się prowadzić przewidywalnie.

Praktyczne pytania przed wyborem frameworka

Przed wdrożeniem Cypress albo Playwright dobrze jest odpowiedzieć konkretnie na kilka pytań. Nie chodzi o tworzenie formalnej ankiety, lecz o ujawnienie wymagań, które często wychodzą na jaw dopiero po kilku miesiącach pracy.

  • Czy aplikacja musi być sprawdzana w więcej niż jednym silniku przeglądarki?
  • Czy testy obejmują logowanie w zewnętrznej domenie, płatności, system SSO albo wiele subdomen?
  • Czy zespół potrzebuje testów wyłącznie w JavaScripcie i TypeScripcie, czy także w Pythonie, Javie lub .NET?
  • Gdzie częściej analizowane są błędy: lokalnie na komputerze programisty czy w artefaktach z CI?
  • Jak duży ma być docelowy zestaw testów i ile czasu może zajmować jego wykonanie w pull requeście?
  • Czy organizacja zaakceptuje dodatkową usługę chmurową, czy woli przechowywać wyniki i nagrania na własnej infrastrukturze?

Dopiero zestaw odpowiedzi daje podstawę do racjonalnego wyboru. Cypress vs Playwright to nie konkurs na najładniejszą składnię. To decyzja wpływająca na codzienną pracę programistów, testerów, osób utrzymujących CI/CD i zespołu odpowiedzialnego za jakość produktu.

Dwa podejścia do automatyzacji przeglądarki

Jak działa Cypress i co z tego wynika dla testów

Cypress został zaprojektowany tak, aby autor testu mógł wygodnie obserwować zachowanie aplikacji. Narzędzie działa blisko testowanej strony i oferuje własny mechanizm wykonywania poleceń oraz rozbudowany widok przebiegu testu. W praktyce oznacza to, że osoba pisząca scenariusz może zobaczyć kolejne kroki, stan DOM, żądania sieciowe i odpowiedzi serwera bez budowania osobnego zestawu narzędzi diagnostycznych.

Zbliżenie na kodowanie wspierane przez AI z opcjami debugowania
Źródło: Pexels | Autor: Daniil Komov

Jedną z charakterystycznych cech Cypress jest automatyczne ponawianie prób dla wielu operacji. Gdy test oczekuje na element interfejsu, nie musi od razu kończyć się błędem tylko dlatego, że aplikacja potrzebowała chwili na wyrenderowanie widoku. Cypress będzie przez określony czas sprawdzał, czy element pojawił się, czy jest widoczny albo czy spełnia wskazany warunek. To ogranicza potrzebę ręcznego wstawiania stałych opóźnień, takich jak wait na dwie sekundy, które zwykle są źródłem niestabilnych testów.

Przykładowy test rejestracji w Cypress może być bardzo zwięzły:

cy.visit('/rejestracja');
cy.get('[data-testid="email"]').type('anna@example.test');
cy.get('[data-testid="password"]').type('BezpieczneHaslo123!');
cy.get('[data-testid="submit"]').click();
cy.contains('Konto zostało utworzone').should('be.visible');

Taki zapis jest przystępny dla osób znających JavaScript. Jednocześnie prostota składni nie zwalnia z projektowania stabilnych testów. Selektor oparty na data-testid jest zwykle bezpieczniejszy niż selektor zależny od klas CSS, które mogą się zmienić podczas poprawki stylów. Komunikat końcowy powinien potwierdzać rzeczywisty efekt biznesowy, a nie jedynie fakt, że kliknięto przycisk.

Granice modelu Cypress

Architektura Cypress daje dużą wygodę w typowych scenariuszach frontendowych, ale ma też konsekwencje. Testy obejmujące wiele domen, zewnętrzne systemy uwierzytelniania, nietypowe przekierowania czy osadzone dokumenty wymagają dokładnego sprawdzenia aktualnych możliwości i konfiguracji. Część przypadków można obsłużyć mechanizmami przewidzianymi przez Cypress, jednak nie zawsze będzie to tak bezpośrednie jak testowanie jednej aplikacji pod własną domeną.

Dobrym przykładem jest rejestracja, po której użytkownik zostaje przekierowany do zewnętrznego dostawcy logowania. W lokalnym środowisku można czasem zastąpić taki element atrapą lub użyć testowego dostawcy tożsamości. W środowisku integracyjnym trzeba już rozstrzygnąć, czy test ma sprawdzać pełny przepływ między domenami, czy jedynie kontrakt integracji. Nie każdy przypadek wymaga automatyzowania całego świata zewnętrznego w jednym teście E2E.

Jak działa Playwright i dlaczego często wybiera się go do szerszych scenariuszy

Playwright steruje przeglądarkami przez nowoczesne interfejsy automatyzacji i mocno wykorzystuje konteksty przeglądarki. Kontekst można rozumieć jako lekką, odizolowaną przestrzeń użytkownika: ma własne ciasteczka, local storage, uprawnienia i stan sesji. Dzięki temu kolejne testy mogą działać niezależnie, bez konieczności otwierania pełnego nowego okna przeglądarki dla każdego scenariusza.

Izolacja zmniejsza ryzyko, że test logowania wpłynie na test koszyka albo że dane pozostawione po poprzednim scenariuszu zmienią wynik następnego. To szczególnie przydatne w dużych zestawach testów uruchamianych równolegle. Zamiast próbować ręcznie „sprzątać” stan po każdym teście, można projektować przypadki tak, aby od początku otrzymywały oddzielne środowisko przeglądarkowe.

Playwright zapewnia natywną obsługę Chromium, Firefox i WebKit. To ważne, ponieważ aplikacja, która działa bez zarzutu w Chromium, może inaczej zachowywać się w silniku WebKit. WebKit jest silnikiem kojarzonym z Safari, dlatego testy w tym środowisku pomagają wcześniej wychwycić część problemów typowych dla ekosystemu Apple. Nie zastępują jednak testowania na rzeczywistych urządzeniach, systemach operacyjnych ani konkretnych wersjach przeglądarek używanych przez klientów.

Playwright także stosuje mechanizmy automatycznego oczekiwania. Akcje takie jak kliknięcie czy wpisanie tekstu nie powinny odbywać się, dopóki element nie jest gotowy do interakcji. To ważne sprostowanie: automatyczne oczekiwanie nie jest przewagą zarezerwowaną wyłącznie dla Cypress. W obu narzędziach podstawą stabilności jest korzystanie z wbudowanych mechanizmów synchronizacji zamiast maskowania problemów sztywnymi opóźnieniami.

import { test, expect } from '@playwright/test';

test('użytkownik zakłada konto', async ({ page }) => {
  await page.goto('/rejestracja');
  await page.getByTestId('email').fill('anna@example.test');
  await page.getByTestId('password').fill('BezpieczneHaslo123!');
  await page.getByTestId('submit').click();

  await expect(page.getByText('Konto zostało utworzone')).toBeVisible();
});

Wiele stron, kart i kontekstów w jednym scenariuszu

Playwright bywa wygodnym wyborem, gdy scenariusz obejmuje kilka kart, okno wyskakujące albo przejście do innej domeny. Dotyczy to na przykład systemu, w którym użytkownik inicjuje płatność w sklepie, przechodzi do operatora płatniczego w środowisku testowym, a następnie wraca do potwierdzenia zamówienia. Oczywiście należy rozważnie zdecydować, które elementy zewnętrznej integracji są rzeczywiście testowane end-to-end, a które powinny zostać sprawdzone kontraktowo lub przez sandbox dostawcy.

Monitor komputera z kodem i danymi cyberbezpieczeństwa
Źródło: Pexels | Autor: Tima Miroshnichenko

Ta elastyczność nie oznacza, że każdy projekt powinien automatycznie wybierać Playwright. Szerszy zakres możliwości wymaga też świadomych konwencji. Jeśli każdy zespół stworzy własny sposób zarządzania logowaniem, danymi testowymi i fixture’ami, repozytorium szybko stanie się trudne w utrzymaniu niezależnie od użytego frameworka.

Codzienna praca z testami: ergonomia, debugowanie i czytelność kodu

Interfejs testera i analiza nieudanego przebiegu

Cypress wyróżnia się interaktywnym podejściem do lokalnego uruchamiania testów. Widok test runnera pozwala przechodzić po kolejnych komendach i sprawdzać, co aplikacja pokazywała na danym etapie. Dla osoby rozpoczynającej automatyzację testów frontendowych taka forma jest bardzo intuicyjna. Zamiast czytać wyłącznie log błędu, można zobaczyć sekwencję działań prowadzących do problemu. [3]

Playwright stawia mocno na artefakty diagnostyczne. Ślady wykonania testu, nazywane trace, mogą zawierać między innymi kolejne akcje, zrzuty ekranu, informacje o sieci i stan strony. Do tego dochodzą nagrania oraz screenshoty konfigurujące się na przykład tylko dla błędnych przebiegów. Ten model jest szczególnie wygodny, gdy błąd występuje wyłącznie na serwerze CI, gdzie autor testu nie może po prostu otworzyć przeglądarki i odtworzyć sytuacji ręcznie.

W praktyce są to dwa style diagnozowania problemu. Cypress zachęca do wizualnego śledzenia testu podczas jego lokalnego wykonywania. Playwright umożliwia dokładną analizę materiału zebranego po zakończonym przebiegu. Zespół działający głównie lokalnie może docenić pierwsze podejście. Organizacja, w której setki testów przechodzą przez współdzieloną infrastrukturę CI, często mocniej skorzysta z dobrze archiwizowanych śladów i nagrań.

Artefakty z CI powinny być częścią procesu, a nie dodatkiem

Niezależnie od wybranego narzędzia, pipeline powinien przechowywać materiały potrzebne do diagnozy błędu. Minimalny zestaw najczęściej obejmuje raport HTML, logi testowe, screenshoty nieudanych przypadków i nagrania lub ślady wykonania. Bez tych danych zespół otrzymuje komunikat „test nie przeszedł”, ale nie ma dowodu, czy przyczyną był błąd aplikacji, problem z danymi testowymi, niedostępność usługi czy chwilowe przeciążenie środowiska.

Nie ma sensu przechowywać wszystkich ciężkich artefaktów bez limitu. Rozsądniejsza polityka zakłada zachowanie pełnych danych dla błędnych przebiegów, krótszy okres retencji i kontrolę dostępu. Materiały z testów mogą zawierać adresy e-mail, identyfikatory użytkowników lub elementy danych biznesowych, nawet jeśli środowisko jest testowe.

Języki, API testowe i wejście nowych osób do projektu

Cypress jest przede wszystkim narzędziem dla ekosystemu JavaScript i TypeScript. W wielu zespołach frontendowych jest to zaleta, a nie ograniczenie. Kod aplikacji, konfiguracja narzędzi budujących i testy mogą znajdować się w jednym języku, co upraszcza onboarding oraz przeglądy pull requestów.

Playwright oferuje biblioteki dla JavaScriptu i TypeScriptu, ale również dla Pythona, Javy oraz .NET. Ta wielojęzyczność ma realną wartość w organizacjach, w których testami zajmują się zespoły pracujące w różnych technologiach albo gdy automatyzacja przeglądarki jest częścią większego systemu testowego. Nie należy jednak traktować wielu języków jako celu samego w sobie. Jeśli jeden produkt ma testy w czterech językach bez wspólnych zasad, koszt utrzymania może wzrosnąć szybciej niż korzyści.

Różny jest także styl asynchroniczności. Cypress zarządza kolejką komend w charakterystyczny dla siebie sposób, natomiast Playwright w JavaScripcie i TypeScripcie wykorzystuje zwykle async/await. Dla programistów przyzwyczajonych do współczesnego kodu asynchronicznego Playwright może być bardziej naturalny. Dla osób stawiających pierwsze kroki w automatyzacji Cypress często daje prostsze doświadczenie dzięki spójnemu API i interaktywnemu środowisku.

Czytelny test opisuje zachowanie, a nie budowę komponentu

Bez względu na narzędzie, test nie powinien być kroniką kliknięć w przypadkowe elementy DOM. Nazwa scenariusza ma opisywać wartość dla użytkownika, na przykład „administrator może zablokować konto użytkownika”, a nie „kliknięcie przycisku disabled ustawia klasę active”. Ten drugi przypadek jest bliższy testowi komponentu lub testowi jednostkowemu.

Stabilny scenariusz E2E korzysta z selektorów, które wyrażają intencję. Dobrze sprawdzają się role dostępności, etykiety pól oraz jawne atrybuty testowe. Kruchy test opiera się na długich ścieżkach CSS, indeksach typu :nth-child(4) albo nazwach klas generowanych przez bibliotekę stylów. Zmiana układu strony może wtedy zepsuć test, mimo że funkcja dostępna dla użytkownika nadal działa prawidłowo.

  • Preferuj data-testid dla elementów, których semantyka nie jest oczywista.
  • Wykorzystuj role i nazwy dostępne dla użytkownika, gdy poprawiają czytelność testu.
  • Nie testuj w E2E każdego detalu wizualnego komponentu.
  • Oddziel przygotowanie danych od właściwego scenariusza biznesowego.
  • Buduj małe, jasno nazwane funkcje pomocnicze zamiast tworzyć rozbudowane, ukryte abstrakcje.

Przeglądarki, równoległość i czas działania testów E2E

Testy wieloprzeglądarkowe bez pozornej pewności

Testowanie w jednej przeglądarce jest lepsze niż brak testów, ale nie daje pełnego obrazu zachowania aplikacji. Różnice między silnikami dotyczą między innymi renderowania CSS, obsługi niektórych API, zachowania formularzy, mechanizmów prywatności i wydajności skryptów. Jeśli produkt ma użytkowników Safari lub Firefox, sprawdzanie wyłącznie Chromium może pozostawić istotną lukę jakościową.

Playwright upraszcza uruchamianie tego samego zestawu testów w Chromium, Firefox i WebKit. Konfiguracja projektów pozwala traktować poszczególne przeglądarki jako równoległe cele. Nie oznacza to, że każdy test musi być wykonywany wszędzie. Zestaw można podzielić: krytyczne ścieżki, takie jak logowanie, zakup, rejestracja i zarządzanie kontem, mogą działać w kilku silnikach, a mniej ryzykowne przypadki tylko w głównej przeglądarce używanej przez zespół. [2]

Cypress również obsługuje testowanie w popularnych przeglądarkach, jednak organizacje, dla których automatyczne pokrycie Chromium, Firefox i WebKit jest twardym wymaganiem, często uznają Playwright za bardziej naturalny wybór. Przy ocenie nie należy mylić testu w WebKit z pełnym testem Safari na każdym urządzeniu Apple. Automatyzacja daje silny sygnał jakościowy, ale nie eliminuje potrzeby okresowej weryfikacji na realnych konfiguracjach.

Równoległość nie polega wyłącznie na zwiększeniu liczby workerów

Najprostszy sposób skrócenia czasu wykonania testów polega na uruchomieniu kilku procesów równolegle. W praktyce efekt zależy jednak od tego, czy środowisko testowe, baza danych, backend i sama infrastruktura CI są gotowe na większe obciążenie. Dziesięć workerów nie przyspieszy pipeline’u dziesięciokrotnie, jeśli wszystkie scenariusze próbują jednocześnie zakładać użytkowników w tej samej bazie, wysyłać wiadomości przez ten sam sandbox lub korzystać z ograniczonego środowiska stagingowego.

Playwright ma wbudowany model workerów, który pozwala wykonywać pliki testowe równolegle na jednej maszynie CI. Można również podzielić cały zestaw na shardy, czyli niezależne części uruchamiane na kilku agentach pipeline’u. To podejście dobrze działa przy większych repozytoriach, gdzie czas testów zaczyna mieć bezpośredni wpływ na tempo dostarczania zmian. [4]

// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  workers: process.env.CI ? 4 : undefined,
  retries: process.env.CI ? 1 : 0,
  reporter: [['html'], ['list']],
});

Sama konfiguracja liczby workerów jest tylko początkiem. Warto obserwować, jak zmienia się czas poszczególnych plików testowych. Częstym problemem są nierówno podzielone zestawy: dziewięć workerów kończy pracę po dwóch minutach, a jeden pozostaje zajęty przez kolejnych osiem minut, ponieważ otrzymał najcięższy scenariusz. W takim przypadku dodatkowa moc obliczeniowa jest dostępna, ale pipeline nadal czeka na pojedynczy wąski gardło.

Zbliżenie na interfejs programu do edycji audio i wideo z falami dźwiękowymi
Źródło: Pexels | Autor: Pixabay

Cypress także można uruchamiać równolegle w kilku zadaniach CI, dzieląc specyfikacje pomiędzy maszyny. Przy większej skali szczególnego znaczenia nabiera inteligentne rozdzielanie testów według ich historycznego czasu wykonania. Bez tego prosty podział według liczby plików może prowadzić do nierównego wykorzystania agentów, bo jeden plik może zawierać krótki test formularza, a drugi rozbudowany przepływ zamówienia z wieloma krokami.

Najpierw zmierz czas, potem kupuj kolejne zasoby CI

Rosnąca liczba maszyn wykonawczych generuje koszt, ale nie zawsze usuwa źródło problemu. Przed zwiększeniem równoległości warto odpowiedzieć na kilka praktycznych pytań: które testy są najwolniejsze, czy czas tracony jest w przeglądarce czy po stronie API oraz czy środowisko testowe odpowiada równie szybko pod obciążeniem jak przy pojedynczym przebiegu.

Długie testy E2E często są objawem nie tylko rozbudowanego scenariusza, lecz także nieefektywnego przygotowania danych. Jeśli każdy przypadek zakłada konto przez interfejs, tworzy katalog produktów, wykonuje pełną konfigurację organizacji i dopiero na końcu sprawdza jedną funkcję, koszt rośnie wykładniczo. Dane potrzebne do scenariusza można w wielu sytuacjach przygotować przez kontrolowane API, fixture lub bezpośredni mechanizm testowy aplikacji. Interfejs użytkownika powinien weryfikować zachowanie, które rzeczywiście ma przejść przez interfejs.

Nie chodzi o omijanie ważnych kroków biznesowych. Test zakupu powinien nadal sprawdzać, czy użytkownik potrafi dodać produkt do koszyka i złożyć zamówienie. Nie musi jednak za każdym razem ręcznie tworzyć produktu w panelu administratora, jeśli celem scenariusza nie jest testowanie administracji katalogiem.

Dane testowe są warunkiem bezpiecznej równoległości

Testy uruchamiane sekwencyjnie czasem przypadkowo działają poprawnie mimo ukrytych zależności. Jeden scenariusz tworzy użytkownika, drugi korzysta z tego samego konta, a trzeci usuwa dane po zakończeniu. Gdy takie przypadki zostaną uruchomione równolegle, pojawiają się błędy trudne do odtworzenia: konto jest już zablokowane, zamówienie zmieniło status albo rekord został usunięty przez inny worker.

Każdy scenariusz powinien mieć możliwie własne dane i unikalne identyfikatory. W praktyce pomaga dodawanie do adresów e-mail, nazw organizacji czy numerów zamówień znacznika zawierającego identyfikator przebiegu, workera lub aktualny czas. Dzięki temu test nie tylko zmniejsza ryzyko kolizji, ale też pozostawia po sobie dane łatwiejsze do zidentyfikowania podczas analizy błędu.

const runId = `${Date.now()}-${process.env.CI_NODE_INDEX ?? 'local'}`;
const email = `e2e-${runId}@example.test`;

Istotne jest również sprzątanie danych, ale nie należy opierać stabilności całego zestawu wyłącznie na kodzie wykonywanym po teście. Gdy proces zostanie przerwany, agent CI utraci połączenie albo środowisko zwróci błąd, kod porządkujący może się nie uruchomić. Bezpieczniejszy model łączy okresowe czyszczenie danych testowych po stronie środowiska z mechanizmem wygasania rekordów oznaczonych jako testowe.

Retry może chronić pipeline, ale nie powinno ukrywać problemów

Ponowienie nieudanego testu bywa uzasadnione w środowisku rozproszonym. Chwilowy błąd sieciowy, restart usługi zależnej lub problem infrastruktury mogą wystąpić mimo poprawnego kodu aplikacji. Retry nie powinno jednak być sposobem na „zazielenienie” niestabilnego zestawu. Test, który regularnie przechodzi dopiero za drugim podejściem, nadal jest sygnałem jakościowym wymagającym analizy.

Warto raportować przypadki zakończone powodzeniem po ponowieniu jako osobną kategorię. Takie wyniki pokazują, gdzie powstaje niestabilność: w konkretnym module, na wybranym agencie CI, przy danej klasie danych albo w godzinach większego obciążenia środowiska. Bez tej widoczności retry zamienia się w mechanizm maskujący, a zespół stopniowo traci zaufanie do testów E2E.

Dobry pipeline odróżnia błąd produktu od awarii infrastruktury. Jeżeli testy nie mogą połączyć się z aplikacją, DNS nie odpowiada albo środowisko docelowe zwraca błędy dla wszystkich scenariuszy, sensowniejsze może być oznaczenie przebiegu jako problemu platformowego niż automatyczne traktowanie każdego testu jako defektu funkcjonalnego.

Jak przełożyć wymagania projektu na decyzję technologiczną

Cypress będzie praktycznym rozwiązaniem, gdy priorytetem jest szybkie tworzenie i lokalne diagnozowanie testów w repozytorium opartym na JavaScripcie lub TypeScripcie, a scenariusze są względnie typowe dla pojedynczej aplikacji webowej. Jego ergonomia pomaga zespołowi zacząć automatyzację bez budowania rozbudowanej warstwy pomocniczej już na pierwszym etapie projektu.

Playwright warto potraktować jako mocnego kandydata, gdy testy mają obejmować bardziej złożone przepływy między domenami, kilka kart, większą równoległość w CI lub obowiązkowe pokrycie wielu silników przeglądarek. Dobrze sprawdza się również wtedy, gdy organizacja potrzebuje spójnej automatyzacji przeglądarki w zespołach używających różnych języków programowania.

Najważniejsza decyzja nie dotyczy jednak samej biblioteki. Zespół powinien ustalić, które ścieżki biznesowe zasługują na kosztowną w utrzymaniu ochronę E2E, jak będą przygotowywane dane, kto reaguje na niestabilne przebiegi oraz jakie informacje mają znaleźć się w raporcie z CI. Dopiero na takim fundamencie Cypress albo Playwright przestają być jedynie narzędziami do klikania po stronie i stają się wiarygodnym elementem procesu jakościowego.

Pilotaż powinien sprawdzać realny przepływ, a nie tylko pierwszy test

Porównanie narzędzi na podstawie krótkiego przykładu logowania zwykle nie daje wiarygodnej odpowiedzi. Oba rozwiązania pozwolą szybko otworzyć stronę, wypełnić formularz i sprawdzić komunikat sukcesu. Różnice ujawniają się dopiero wtedy, gdy pilotaż obejmuje elementy, które rzeczywiście generują koszt utrzymania: uwierzytelnianie, dane testowe, komunikację z usługami zewnętrznymi, działanie w CI oraz diagnozowanie nieudanego przebiegu.

Dobry proof of concept nie musi być duży. Wystarczą dwa lub trzy scenariusze reprezentujące różne klasy ryzyka. Przykładowo może to być ścieżka użytkownika zalogowanego, proces wymagający danych przygotowanych przez API oraz przypadek obejmujący przekierowanie lub nową kartę. Istotne jest, aby każdy z nich został uruchomiony lokalnie i wielokrotnie w pipeline’ie, najlepiej przy równoległym obciążeniu środowiska.

W trakcie pilotażu warto mierzyć nie tylko czas napisania testu. Równie ważne są odpowiedzi na bardziej operacyjne pytania: ile czasu zajmuje zrozumienie błędu po nieudanym przebiegu, czy nowa osoba w zespole potrafi uruchomić zestaw bez długiej konfiguracji oraz czy testy zachowują się przewidywalnie po zmianie danych i kolejności wykonania.

Koszt utrzymania zaczyna się po pierwszych kilkudziesięciu testach

Początkowo automatyzacja E2E wygląda jak prosty przyrost kodu testowego. Po pewnym czasie repozytorium zaczyna jednak wymagać własnej architektury. Pojawiają się funkcje do logowania, przygotowywania danych, obsługi uprawnień, przechwytywania żądań, czyszczenia stanu oraz raportowania wyników. To właśnie jakość tych elementów częściej decyduje o trwałości zestawu niż pojedyncze różnice w składni Cypressa i Playwrighta.

Warto ograniczać nadmierną abstrakcję. Rozbudowana warstwa pomocnicza potrafi ukryć intencję scenariusza równie skutecznie jak źle napisany kod aplikacji. Metoda o nazwie createReadyToPurchaseCustomer() może być użyteczna, jeśli opisuje konkretny stan biznesowy. Ogólny mechanizm budujący użytkownika przez kilkanaście opcjonalnych parametrów szybko staje się trudny do zrozumienia i podatny na przypadkowe użycie.

Praktycznym kompromisem jest pozostawianie kroków istotnych dla użytkownika w samym teście, a techniczne przygotowanie stanu przenoszenie do niewielkich, dobrze nazwanych funkcji pomocniczych. Dzięki temu osoba czytająca scenariusz widzi przebieg zakupu, zmiany planu lub anulowania subskrypcji, bez konieczności analizowania szczegółów tworzenia danych w tle.

async function createActiveSubscription(api, customerId: string) {
  return api.post('/test-support/subscriptions', {
    data: {
      customerId,
      plan: 'pro',
      status: 'active',
    },
  });
}

Tego rodzaju endpoint powinien istnieć wyłącznie w kontrolowanym środowisku testowym albo być odpowiednio zabezpieczony. Nie należy dodawać do produkcyjnego API otwartych mechanizmów pozwalających dowolnie tworzyć konta, płatności czy uprawnienia tylko po to, aby uprościć testy.

Standaryzacja jest ważniejsza niż pełna unifikacja za wszelką cenę

W większej organizacji może się zdarzyć, że część produktów używa już Cypressa, a nowe zespoły zaczynają pracę z Playwrightem. Taka sytuacja sama w sobie nie jest błędem. Problem pojawia się wtedy, gdy każde repozytorium tworzy własne zasady uruchamiania testów, własny format raportów i odmienną definicję gotowości zmiany do wdrożenia.

Tablica kanban z wykresami i analizą danych na ekranie w biurze
Źródło: Pexels | Autor: Jakub Zerdzicki

Nawet przy dwóch narzędziach warto ujednolicić proces wokół nich. Wspólne mogą być zasady oznaczania testów krytycznych, sposób tworzenia danych, minimalny zestaw kontroli przed mergem, polityka retry oraz sposób zgłaszania niestabilnych scenariuszy. Dzięki temu różnica technologiczna nie przeradza się w różnicę jakościową między zespołami.

Nie zawsze opłaca się też migrować istniejący, stabilny zestaw testów tylko po to, aby cała firma korzystała z jednego frameworka. Migracja ma sens wtedy, gdy obecne rozwiązanie realnie blokuje rozwój: utrudnia pokrycie wymaganych przepływów, nie mieści się w ograniczeniach CI albo generuje stały koszt operacyjny. Jeżeli zestaw jest utrzymywany, zrozumiały i daje wiarygodny sygnał, przepisanie go może chwilowo obniżyć, a nie podnieść poziom jakości.

Testy E2E powinny chronić granice systemu, a nie zastępować wszystkie inne testy

Niezależnie od użytego narzędzia testy end-to-end pozostają najwolniejszą i najdroższą warstwą automatyzacji. Ich największą wartością jest sprawdzanie miejsc, w których łączą się komponenty: interfejs użytkownika, backend, autoryzacja, płatności, powiadomienia lub systemy partnerów. Nie są natomiast dobrym miejscem do szczegółowego sprawdzania każdej wariacji walidacji formularza czy wszystkich kombinacji reguł biznesowych.

Jeżeli ten sam błąd można szybko i wiarygodnie wykryć testem jednostkowym albo integracyjnym, zwykle nie ma potrzeby tworzenia dla niego wielu scenariuszy przeglądarkowych. Zestaw E2E powinien pozostać na tyle mały, aby zespół traktował jego wyniki poważnie i był gotowy reagować na regresje bez odkładania analizy na później.

Dobrze utrzymywany pakiet nie jest więc zbiorem wszystkich możliwych kliknięć w aplikacji. To celowo wybrana warstwa ochronna dla najważniejszych zachowań produktu, wsparta szybszymi testami niższego poziomu oraz środowiskiem testowym, które pozwala bezpiecznie uruchamiać scenariusze równolegle.

W codziennej pracy najwięcej zyskuje zespół, który regularnie usuwa przestarzałe przypadki, skraca zbyt szerokie scenariusze i analizuje powtarzające się źródła niestabilności. Narzędzie może ułatwić ten proces, ale nie wykona go automatycznie. Wiarygodność testów E2E powstaje przede wszystkim z dyscypliny w projektowaniu danych, kontroli środowiska i szybkiego reagowania na sygnały z pipeline’u.

Najważniejsze wnioski

  • Wybór między Cypress a Playwright powinien wynikać z wymagań projektu i sposobu pracy zespołu, a nie z samej popularności narzędzia.
  • Cypress dobrze pasuje do zespołów frontendowych, które cenią prostą składnię, szybkie rozpoczęcie pracy i wygodne diagnozowanie testów lokalnie.
  • Playwright może być właściwym wyborem przy testach Chromium, Firefox i WebKit, dużej równoległości, izolacji scenariuszy oraz bardziej złożonych przepływach.
  • Przed wdrożeniem trzeba sprawdzić między innymi obsługę wielu domen, zewnętrznego logowania, kart, iframe, języków programowania i artefaktów z CI.
  • Dobrze utrzymany zestaw testów nie wymaga migracji tylko dlatego, że inne narzędzie zyskuje popularność. Migracja ma sens, gdy obecne ograniczenia utrudniają rozwój projektu.

Źródła