E2E тестирование

E2E (End-to-End) тестирование проверяет работу приложения целиком: от пользовательского интерфейса до серверной логики и обратно. При использовании Naive UI в проектах на Vue.js важно понимать, как компоненты библиотеки взаимодействуют с DOM и как корректно эмулировать действия пользователя.

Настройка окружения

Для E2E тестирования современных проектов часто применяют Cypress или Playwright. Установка Cypress выполняется командой:

npm install cypress --save-dev

После установки создается структура папок cypress/, где размещаются тесты, фикстуры и скрипты конфигурации. Для корректного тестирования компонентов Naive UI необходимо, чтобы приложение было доступно через локальный сервер (npm run serve или vite dev).

Особенности работы с Naive UI

Naive UI использует виртуальный DOM и глубокую реактивность Vue 3. Это накладывает несколько специфических требований:

  • Асинхронное обновление состояния: многие компоненты, такие как NSelect, NModal или NDataTable, обновляют DOM после реактивных изменений. В E2E тестах необходимо использовать ожидания (cy.wait, cy.get().should('exist')) для корректной проверки состояния.
  • Динамическая отрисовка: компоненты с ленивая подгрузка содержимого (NDrawer, NPopover) создают элементы в DOM только при открытии. Для взаимодействия с ними требуется предварительное триггерное событие (click или hover).
  • Селекторы: использование классов Naive UI для поиска элементов нестабильно, так как классы часто генерируются автоматически. Рекомендуется применять data-testid атрибуты для устойчивой идентификации элементов.

Пример теста формы с Naive UI

describe('Форма авторизации', () => {
  beforeEach(() => {
    cy.visit('/login');
  });

  it('Отправка формы с корректными данными', () => {
    cy.get('[data-testid="username"]').type('testuser');
    cy.get('[data-testid="password"]').type('securepass');
    cy.get('[data-testid="login-button"]').click();

    cy.get('[data-testid="welcome-message"]')
      .should('contain.text', 'Добро пожаловать, testuser');
  });

  it('Проверка валидации пустых полей', () => {
    cy.get('[data-testid="login-button"]').click();
    cy.get('[data-testid="username-error"]').should('exist');
    cy.get('[data-testid="password-error"]').should('exist');
  });
});

Особенности:

  • data-testid применяется для стабильной идентификации.
  • Проверка ошибок осуществляется через should('exist').
  • Асинхронное отображение ошибок учитывается автоматически благодаря механизму ожидания Cypress.

Работа с модальными окнами и диалогами

Модальные окна Naive UI, такие как NModal, требуют специальных подходов:

cy.get('[data-testid="open-modal"]').click();
cy.get('.n-modal').should('be.visible');
cy.get('[data-testid="confirm-button"]').click();
cy.get('.n-modal').should('not.exist');

Ключевые моменты:

  • Элементы NModal создаются динамически, поэтому необходимо убедиться, что они появились в DOM перед взаимодействием.
  • Закрытие модального окна следует проверять через отсутствие элемента в DOM (should('not.exist')), а не через видимость.

Тестирование интерактивных компонентов

Компоненты вроде NSelect, NDatePicker, NInputNumber имеют свои нюансы:

  • NSelect требует открытия выпадающего списка перед выбором элемента:

    cy.get('[data-testid="country-select"]').click();
    cy.get('.n-base-select-option').contains('Россия').click();
    cy.get('[data-testid="country-select"]').should('contain.text', 'Россия');
  • NDatePicker часто использует виртуальный календарь. Необходимо кликать по конкретной дате в DOM, а не пытаться напрямую записать значение.

Советы по стабильности тестов

  1. Избегать жёстких селекторов классов Naive UI – они меняются при обновлениях.
  2. Использовать data-testid для всех интерактивных элементов.
  3. Ожидания реактивного обновления: применяются cy.wait() или should('exist'), чтобы избежать проблем с асинхронностью Vue 3.
  4. Разделять тесты по функциональности компонентов – каждый тест должен проверять отдельное поведение.

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

Для автоматизации E2E тестов на CI/CD серверах (GitHub Actions, GitLab CI, Jenkins) рекомендуется:

  • Поднимать локальный сервер приложения перед запуском тестов.
  • Использовать headless режим (cypress run --headless или playwright test --headed false).
  • Сохранять скриншоты и видео при падении тестов для последующего анализа.

Эта структура позволяет комплексно проверять работу Naive UI компонентов в реальных сценариях пользовательского взаимодействия, снижая риск регрессий при обновлениях и обеспечивая стабильность интерфейса.