Интеграция с существующим проектом

Для интеграции Cypress в уже существующий проект на JavaScript или TypeScript используется стандартный пакет npm. Выполняется команда:

npm install cypress --save-dev

После установки Cypress добавляет в проект папку cypress/, содержащую структуру каталогов для тестов (integration), фикстур (fixtures), кастомных команд (support) и конфигурацию. Для открытия интерфейса тестирования используется:

npx cypress open

При первом запуске автоматически создаются шаблонные тесты, которые служат примером структуры и синтаксиса.

Файл конфигурации cypress.config.js или cypress.config.ts позволяет задавать глобальные настройки: базовый URL (baseUrl), таймауты (defaultCommandTimeout), пути к папкам и интеграцию с внешними инструментами, например с CI/CD.


Структура тестов и организация файлов

Для существующего проекта важно правильно организовать тесты, чтобы не нарушить архитектуру приложения:

  • integration — тесты пользовательских сценариев. Здесь лучше создавать подкаталоги по функциональным модулям.
  • fixtures — статические данные, которые могут использоваться в тестах (JSON, CSV, изображения).
  • support — кастомные команды и глобальные хуки. Этот каталог позволяет создать функции, которые будут повторно использоваться в разных тестах.
  • plugins — подключение сторонних плагинов и интеграция с API инструментов разработки.

Использование подкаталогов позволяет избежать хаоса при росте количества тестов и упрощает навигацию.


Написание первых тестов в существующем приложении

Тесты Cypress состоят из сценариев (spec), организованных по принципу describe и it:

describe('Авторизация пользователя', () => {
  it('успешный вход с корректными данными', () => {
    cy.visit('/login')
    cy.get('input[name="username"]').type('admin')
    cy.get('input[name="password"]').type('password123')
    cy.get('button[type="submit"]').click()
    cy.url().should('include', '/dashboard')
  })
})

Основные элементы:

  • cy.visit(url) — открытие страницы.
  • cy.get(selector) — поиск элемента по селектору.
  • cy.type(text) — ввод текста.
  • cy.click() — клик по элементу.
  • cy.should('condition') — проверка состояния.

Важно: тесты должны быть независимыми, чтобы их можно было запускать в любом порядке.


Работа с фикстурами и моками

Фикстуры позволяют отделить данные от логики тестов. Для примера:

cy.fixture('user.json').then((user) => {
  cy.get('input[name="username"]').type(user.username)
  cy.get('input[name="password"]').type(user.password)
})

Для интеграции с backend можно использовать команды cy.intercept() для перехвата запросов и возврата моков:

cy.intercept('POST', '/api/login', { statusCode: 200, body: { token: 'abc123' } })
cy.visit('/login')

Такой подход позволяет тестировать фронтенд независимо от состояния сервера.


Настройка кастомных команд и хуков

В cypress/support/commands.js удобно создавать переиспользуемые функции:

Cypress.Commands.add('login', (username, password) => {
  cy.visit('/login')
  cy.get('input[name="username"]').type(username)
  cy.get('input[name="password"]').type(password)
  cy.get('button[type="submit"]').click()
})

Хуки before, beforeEach, afterEach, after позволяют управлять подготовкой и очисткой данных:

beforeEach(() => {
  cy.fixture('user.json').as('userData')
})

it('авторизация', function () {
  cy.login(this.userData.username, this.userData.password)
})

Интеграция с CI/CD

Cypress легко интегрируется в автоматизированные сборки:

  • GitHub Actions:
jobs:
  cypress-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Установка Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 20
      - run: npm install
      - run: npx cypress run
  • GitLab CI/CD и другие инструменты используют аналогичный подход: установка зависимостей и запуск npx cypress run в контейнере.

Отдельное внимание уделяется захвату видео и скриншотов для анализа падений тестов. В cypress.config.js можно включить:

video: true,
screenshotsFolder: 'cypress/screenshots',
videosFolder: 'cypress/videos'

Работа с существующей кодовой базой

При интеграции Cypress в крупный проект важно:

  • Не дублировать существующие тесты. Существующие unit и интеграционные тесты должны сосуществовать с e2e.
  • Использовать page object pattern для сложных страниц, чтобы облегчить поддержку селекторов:
class LoginPage {
  visit() { cy.visit('/login') }
  fillUsername(name) { cy.get('input[name="username"]').type(name) }
  fillPassword(password) { cy.get('input[name="password"]').type(password) }
  submit() { cy.get('button[type="submit"]').click() }
}

const loginPage = new LoginPage()
loginPage.visit()
loginPage.fillUsername('admin')
loginPage.fillPassword('password123')
loginPage.submit()
  • Минимизировать время выполнения тестов: использовать cy.intercept для моков и оптимизацию сетевых запросов.

Локализация и работа с динамическим контентом

Для приложений с поддержкой нескольких языков важно:

  • Создавать фикстуры с локализованными данными.
  • Использовать селекторы по data-cy атрибутам, чтобы тесты не ломались при изменении текста на странице.
  • Учитывать асинхронный контент, применяя команды cy.wait() и проверку состояния элементов через should.

Интеграция сторонних плагинов

Cypress поддерживает подключение плагинов для:

  • визуального тестирования (cypress-image-snapshot),
  • тестирования API (cypress-plugin-api),
  • управления данными (cypress-faker).

Подключение производится через cypress/plugins/index.js и настройку в cypress.config.js.


Практические рекомендации

  • Разделять тесты по функциональным блокам.
  • Использовать кастомные команды для повторяющихся действий.
  • Мокировать внешние сервисы, чтобы тесты были стабильными.
  • Включать видеозапись и скриншоты для CI/CD.
  • Следить за читаемостью и поддерживаемостью кода тестов.