Czym Cypress Component Testing różni się od testów E2E?
W E2E testujesz działającą aplikację. Może to być serwer deweloperski, ale Next.js zaleca również testowanie buildu produkcyjnego, np. po npm run build i npm run start.
W CT montujesz komponent lub drzewo komponentów w przygotowanej stronie testowej. Cypress uruchamia własny dev server, który kompiluje i serwuje kod; nie uruchamiasz pełnego serwera Next.js.
Izolacja często ułatwia diagnozę i skraca przygotowanie scenariusza. Czas wykonania zależy jednak także od kompilacji, providerów i liczby testów.
Setup Cypress Component Testing w Next.js i TypeScript
Przykłady używają aktualnego API Cypress, React 18/19 oraz integracji Next.js 15/16 z Webpackiem. Sprawdź obsługiwane wersje przed instalacją i zachowaj lockfile. Bundler CT jest osobną konfiguracją od Turbopacka używanego przez aplikację.
Instalacja Cypress Component Testing
Przy pierwszym uruchomieniu Cypress daje nam wybór pomiędzy E2E Testing, a Component Testing - wybierz Component Testing i pozwól mu wygenerować bazową konfigurację. W przypadku Next.js Component Testing, opiera się zwykle na integracji z Webpackiem, więc warto potraktować to jako osobną warstwę testów dla komponentów, a nie próbę uruchamiania całej aplikacji App Router 1:1 wewnątrz Cypressa.
Konfiguracja Cypress CT w projekcie Next.js
Support file dla Cypress Component Testing
Import cypress/react zastąpił adapter cypress/react18 w Cypress 14. Nie przenoś automatycznie tej konfiguracji do starszych wersji. Przewodnik migracji.
Globalny CSS, reset, fonty oraz klasy lub atrybuty motywu muszą być obecne także w CT. Samo zamontowanie komponentu nie uruchamia app/layout.tsx. Zachowaj wygenerowany plik component-index.html i elementy potrzebne integracji Next.js do wstrzykiwania stylów. Konfiguracja stylów w CT.
Przykłady zakładają alias @/ wskazujący katalog kodu aplikacji. Dostosuj importy do własnego tsconfig.json.
Pierwszy test komponentu w Cypress CT
Zacznijmy od prostego komponentu Alert:
Uruchom testy:
Sprawdzenie have.class potwierdza nazwę klasy, a nie jej efekt wizualny. Powyższe testy służą poznaniu API; podobne zachowanie można sprawdzić także w RTL.
Test layoutu, który uzasadnia użycie CT
Poniższy komponent zmienia układ przy szerokości viewportu 600 px. CSS Modules jest importowany razem z komponentem.
Test sprawdza efekt CSS i położenie elementów, których jsdom nie wylicza jak przeglądarka. Rozmiar viewportu nie emuluje jednak całego telefonu, jego dotyku ani wydajności.
Podgląd w runnerze nie jest automatyczną regresją wizualną. Asercje powyżej nie wykryją dowolnej zmiany koloru czy fontu. Porównywanie screenshotów wymaga osobnej konfiguracji, wzorców i stabilnego środowiska renderowania.
Testowanie komponentów React z hookami i stanem
Debounce można zwykle taniej sprawdzić testem hooka lub komponentu w RTL. Poniżej pokazuję kontrolę czasu w Cypress oraz kompletny hook. Ustalony kontrakt: nie wysyłamy zapytania przy montowaniu; zmianę wysyłamy po okresie ciszy, a wyczyszczenie wcześniej wysłanej frazy zgłaszamy jako pusty ciąg.
Testowanie komponentów z kontekstem i providerami
Wiele komponentów zależy od kontekstu, który w CT musisz dostarczyć samodzielnie. Poniższy wariant zastępuje wcześniejszy support file. Zakłada zainstalowany @tanstack/react-query i własny ThemeProvider; dopasuj importy i wymagane propsy do aplikacji. Plik ma rozszerzenie .tsx, ponieważ zawiera JSX.
Każde montowanie tworzy nowy QueryClient, więc cache zapytań nie jest współdzielony między tymi montowaniami. Jeśli aplikacja używa mutacji lub dodatkowych magazynów stanu, skonfiguruj też ich retry i izolację. Nie umieszczaj wspólnego klienta ani store'a na poziomie modułu, jeśli jego dane mogłyby przeciekać między testami.
Cypress Component Testing vs Jest i React Testing Library
RTL jest biblioteką testowania Reacta. Poniższe porównanie dotyczy konkretnie zestawu Jest + RTL w jsdom, nie wszystkich możliwych środowisk RTL.
| Aspekt | Cypress CT | Jest + RTL w jsdom |
|---|---|---|
| Środowisko | Prawdziwa przeglądarka | Implementacja API DOM w Node.js |
| CSS i geometria | Renderowanie po załadowaniu stylów | Brak rzeczywistego layoutu i renderowania |
| Debugowanie | Runner, DOM snapshots, DevTools | Podgląd DOM, debug(), debugger |
| Koszt wykonania | Przeglądarka i kompilacja komponentów | Zwykle mniejszy dla prostych testów |
| Zdarzenia | Zależne od komendy: symulowane lub natywne | Symulacja interakcji w jsdom |
| Konfiguracja | Bundler, style, providery i przeglądarka | Runner, jsdom, transformacja kodu i mocki |
Ograniczenia jsdom dotyczą m.in. geometrii elementów; nie oznacza to, że biblioteka ignoruje każde API związane ze stylami.
Prawdziwa przeglądarka nie oznacza, że wszystkie zdarzenia są natywne. Przykładowo cy.type() symuluje wpisywanie, a cy.press() wysyła natywne zdarzenia klawiatury i nadaje się do nawigacji Tab. Hover i drag and drop wymagają strategii odpowiedniej dla użytej implementacji; samo wywołanie handlera nie sprawdza całej interakcji.
Kiedy Cypress Component Testing wygrywa?
W telegraficznym skrócie:
- Komponent intensywnie korzysta z CSS (animacje, responsive layout),
- Zależy Ci na wizualnym debugowaniu,
- Testujesz interakcje drag & drop, scroll, resize,
- Chcesz spójności z istniejącymi testami Cypress E2E.
Kiedy Jest i React Testing Library wygrywają?
- Kiedy szybkość jest priorytetem (),
- Sprawdzasz formularze, stany ładowania, renderowanie warunkowe lub hooki bez zależności od rzeczywistego layoutu,
- Twój zespół już zna i używa z powodzeniem RTL.
Interceptowanie requestów w Cypress Component Testing
Cypress CT pozwala przez cy.intercept() zastąpić odpowiedzi HTTP dla żądań wykonywanych przez komponent w przeglądarce. Zarejestruj intercept przed montowaniem i dopasuj rzeczywisty URL. Nie uruchamia to Route Handlera Next.js ani nie sprawdza jego implementacji.
Przykład zakłada istniejący UserProfile, który pobiera /api/user/1 i renderuje wskazane dane lub komunikat błędu:
Ograniczenia Cypress Component Testing w projektach Next.js
To jest miejsce, w którym wiele osób próbuje wycisnąć z CT za dużo.
Client Components często nadają się do CT, jeśli ich zależności da się zapewnić w przeglądarce. Sama dyrektywa 'use client' nie gwarantuje izolacji.
Asynchroniczne Server Components nie są obsługiwane przez CT. Prosty, synchroniczny komponent prezentacyjny bez zależności serwerowych można zamontować w izolacji, ale nie sprawdza to wykonania RSC ani cache Next.js.
Routing App Routera nie jest celem CT. Jeśli chcesz testować przejścia między stronami, middleware, auth guardy czy
redirect(), pisz testy E2E.generateMetadata,generateStaticParams, route handlers i cache Next.js to nie są "zachowania komponentu" i nie warto na siłę wrzucać ich do CT.
Zwróć uwagę na zależności charakterystyczne dla Next.js:
next/navigation: hooki routera wymagają odpowiedniego kontekstu lub kontrolowanego zastępstwa. Możesz sprawdzić reakcję UI na podaną ścieżkę, ale prawdziwe przejście między trasami weryfikuj w E2E.next/image: optymalizacja może wymagać endpointu serwera, którego CT nie uruchamia. W teście UI można dostarczyć kontrolowaną odpowiedź lub wariantunoptimized; nie potwierdza to działania optymalizacji produkcyjnej.- Fonty i layout: odtwórz style, klasy, zmienne CSS i dostęp do plików fontów. CT nie renderuje automatycznie głównego layoutu aplikacji.
- Server Actions: zastąp granicę akcji callbackiem, jeśli sprawdzasz stan formularza. Wykonanie na serwerze i autoryzację testuj oddzielnie.
Dokumentacja Next.js opisuje ograniczenia asynchronicznych Server Components oraz funkcji wymagających serwera.
Dobry podział odpowiedzialności wygląda zwykle tak:
- Vitest/Jest: wydzielona logika; RTL z runnerem: hooki i zachowanie UI bez wymagań dotyczących layoutu,
- Cypress CT: komponenty interaktywne, layout zależny od przeglądarki, drag and drop, focus states,
- Cypress/Playwright E2E: krytyczne flow użytkownika, routing, autentykacja, checkout.
Uruchamianie CT w CI i izolacja testów
Po zainstalowaniu zależności z lockfile uruchom:
Środowisko CI musi mieć zainstalowane zgodne wersje Node.js, Cypress, przeglądarki oraz jej zależności systemowych. Możesz użyć wersjonowanego obrazu Cypress z przeglądarkami. CT uruchamia własny dev server, więc nie wymaga wcześniejszego next start. Przeglądarkę i obraz przypnij do wersji, a przy aktualizacjach sprawdź macierz zgodności.
Dla powtarzalności:
- twórz providery i store'y z czystym stanem dla każdego testu,
- rejestruj intercepty oraz stuby w każdym teście lub
beforeEach, - korzystaj z ponawianych asercji i aliasów żądań zamiast stałych opóźnień,
- dla debounce używaj
cy.clock()icy.tick(), - określ viewport, motyw i fonty, jeśli sprawdzasz geometrię,
- zachowuj raporty oraz screenshoty błędów jako artefakty CI.
Cypress izoluje testy CT i resetuje m.in. intercepty oraz kontrolę zegara, ale nie zastępuje to świadomego zarządzania własnymi singletonami i zewnętrznymi danymi. Izolacja testów.
Kiedy koszt dodatkowej warstwy CT się opłaca?
Zacznij od kilku komponentów, których błędy zależą od przeglądarki: układu, focusu, przewijania albo złożonej interakcji. Oceń, czy testy wykrywają regresje pomijane przez dotychczasowy zestaw i czy ich przygotowanie nie wymaga nadmiernego odtwarzania Next.js.
Nie trzeba testować tego samego placeholdera w RTL, CT i E2E. Zachowaj test na najprostszym poziomie, który wiarygodnie sprawdza dane ryzyko. Samo używanie Cypress E2E obniża koszt poznania narzędzia, ale nie przesądza o potrzebie CT.
Dobre praktyki Cypress Component Testing w React i Next.js
Organizacja plików – trzymaj testy CT blisko komponentów lub w dedykowanym cypress/component/:
Data-testid vs role – preferuj role i aria-label (jak RTL), ale data-testid to pragmatyczny fallback.
Dobieraj poziom testu do zależności — CT może sprawdzać formularz z wieloma polami, walidacją i providerem. Liczba komponentów nie przesądza o E2E; decyduje potrzeba prawdziwego routingu, serwera i przepływu aplikacji. Kompletny setup Cypress E2E w App Router — od konfiguracji CI po fixtures i custom commands — opisuję w osobnym artykule o testach E2E w Next.js.


