Współpraca
Blog Cypress — testy e2e i regresja wizualna
Frontend · · 9 min czytania

Cypress — testy e2e i regresja wizualna

Jak używać Cypressa do testów end-to-end i regresji wizualnej — konfiguracja, pierwsze testy, cypress-image-snapshot i integracja z CI/CD.

Cypress Testing JavaScript

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ę.