Czym jest Cypress?
Cypress to nowoczesne narzędzie do testowania aplikacji webowych. W odróżnieniu od Selenium, działa bezpośrednio w przeglądarce — nie przez WebDriver — co sprawia, że testy są szybsze, bardziej stabilne i dają lepszy dostęp do stanu aplikacji podczas wykonywania.
Cypress obsługuje trzy kategorie testów:
e2e (end-to-end) symulujące prawdziwe ścieżki użytkownika,
komponentowe dla izolowanych komponentów React/Vue/Angular,
oraz wizualną regresję przez dodatkowe pluginy (np. cypress-image-snapshot).
Cypress jest bezpłatny i open source. Płatna jest jedynie platforma Cypress Cloud (dawniej Dashboard) do przechowywania wyników testów i nagrań — ale w wielu projektach nie jest potrzebna.
Instalacja i konfiguracja
Cypress instalujesz jako zależność deweloperską przez npm lub yarn:
# Instalacja
npm install cypress --save-dev
# Otwarcie interfejsu graficznego
npx cypress open
# Uruchomienie testów headless (CI)
npx cypress run
Po pierwszym uruchomieniu Cypress tworzy katalog cypress/
z przykładowymi testami. Konfigurację trzymasz w cypress.config.js
(lub .ts):
// cypress.config.js
const { defineConfig } = require('cypress');
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3000', // adres testowanej aplikacji
viewportWidth: 1280,
viewportHeight: 720,
video: false, // wyłącz nagrania w CI (szybciej)
screenshotOnRunFailure: true,
specPattern: 'cypress/e2e/**/*.cy.js',
setupNodeEvents(on, config) {
// rejestracja pluginów
},
},
});
Pierwsze testy e2e
Testy e2e symulują ścieżkę użytkownika od wejścia na stronę do wykonania akcji. Cypress używa API opartego na łańcuchowaniu komend:
// cypress/e2e/kontakt.cy.js
describe('Formularz kontaktowy', () => {
beforeEach(() => {
cy.visit('/kontakt');
});
it('powinien wyświetlić formularz', () => {
cy.get('h1').should('contain', 'Kontakt');
cy.get('form#kontakt').should('be.visible');
});
it('powinien walidować puste pola', () => {
cy.get('button[type="submit"]').click();
cy.get('.form-error')
.should('be.visible')
.and('contain', 'Wypełnij wymagane pola');
});
it('powinien wysłać formularz z poprawnymi danymi', () => {
cy.get('#imie').type('Jan Kowalski');
cy.get('#email').type('jan@example.com');
cy.get('#wiadomosc').type('Treść testowej wiadomości');
cy.intercept('POST', '/api/kontakt', { statusCode: 200, body: { ok: true } })
.as('wyslijFormularz');
cy.get('button[type="submit"]').click();
cy.wait('@wyslijFormularz');
cy.get('.sukces-komunikat').should('be.visible');
});
});
Ważne: Używaj cy.intercept() do mockowania
wywołań sieciowych w testach. Nie testuj prawdziwego backendu w e2e —
testy powinny być deterministyczne i niezależne od stanu serwera.
Regresja wizualna
Regresja wizualna to technika polegająca na porównywaniu screenshotów aplikacji z poprzednimi "zaakceptowanymi" wersjami. Każda niezamierzona zmiana CSS lub layoutu spowoduje błąd testu.
Popularny plugin to @percy/cypress (zewnętrzna usługa) lub
cypress-image-snapshot (lokalnie):
// Instalacja cypress-image-snapshot
// npm install cypress-image-snapshot --save-dev
// cypress/support/commands.js
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command';
addMatchImageSnapshotCommand({
failureThreshold: 0.03, // tolerancja 3% różnicy pikselowej
failureThresholdType: 'percent',
customSnapshotsDir: 'cypress/snapshots',
});
// cypress/e2e/visual.cy.js
describe('Regresja wizualna', () => {
it('strona główna wygląda poprawnie', () => {
cy.visit('/');
cy.matchImageSnapshot('strona-glowna');
});
it('hero section wygląda poprawnie', () => {
cy.visit('/');
cy.get('.hero').matchImageSnapshot('hero-section');
});
it('responsywnie na mobile', () => {
cy.viewport(375, 812); // iPhone 14
cy.visit('/');
cy.matchImageSnapshot('strona-glowna-mobile');
});
});
Przy pierwszym uruchomieniu Cypress zapisuje screenshoty jako "bazę".
Każde kolejne uruchomienie porównuje z bazą — jeśli różnica przekracza
próg (failureThreshold) test nie przechodzi.
Gdy zmiany są celowe, aktualizujesz snapshoty przez usunięcie pliku bazy
lub flagę --env updateSnapshots=true.
Integracja z CI/CD
Cypress działa świetnie w środowiskach CI (GitHub Actions, GitLab CI, CircleCI). Przykład z GitHub Actions:
# .github/workflows/e2e.yml
name: E2E Tests
on: [push, pull_request]
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install & Build
run: |
npm ci
npm run build
- name: Start dev server (background)
run: npm start &
env:
PORT: 3000
- name: Wait for server
run: npx wait-on http://localhost:3000 --timeout 30000
- name: Run Cypress tests
uses: cypress-io/github-action@v6
with:
wait-on: 'http://localhost:3000'
browser: chrome
headless: true
Wskazówka: Używaj oficjalnego cypress-io/github-action
zamiast ręcznego npx cypress run. Ten action automatycznie cachuje
binarkę Cypress, co skraca czas CI o 30-60 sekund przy każdym uruchomieniu.
Dobre praktyki
- Selektory
data-cy— nie testuj przez klasy CSS (zmieniają się). Dodaj własne atrybuty do elementów:<button data-cy="submit-btn"> - Testuj zachowanie, nie implementację — sprawdzaj co widzi użytkownik, nie wewnętrzny stan aplikacji
- Izoluj testy — każdy test powinien być niezależny od kolejności
- Seeduj dane testowe — przez API lub bezpośrednio przed każdą grupą testów
- Nie testuj wszystkiego przez e2e — logika biznesowa należy do unit/integration testów (jest szybsza)
Podsumowanie
Cypress to najlepsze narzędzie do e2e i regresji wizualnej w ekosystemie webowym. Jasne API, świetna dokumentacja i natywna integracja z popularnymi CI/CD sprawiają, że wdrożenie zestawu testów nie zajmuje dużo czasu, a zysk jest duży — każda zmiana kodu jest sprawdzana automatycznie zanim trafi na produkcję.