Testing Library для Quasar

Для начала необходимо убедиться, что проект Quasar использует Vue 3, так как Testing Library интегрируется с @testing-library/vue. Установка выполняется через npm или yarn:

npm install --save-dev @testing-library/vue @testing-library/jest-dom

или

yarn add --dev @testing-library/vue @testing-library/jest-dom

После установки важно настроить Jest или Vitest для интеграции с Testing Library. Для Quasar CLI проекты с Jest настройки обычно включают добавление в jest.config.js следующего:

setupFilesAfterEnv: ['<rootDir>/tests/setup.js'],

Файл setup.js подключает расширения Jest DOM:

import '@testing-library/jest-dom';

Основные концепции Testing Library

Testing Library строится вокруг идеи тестирования компонентов так, как их использует пользователь. Основные принципы:

  • Рендеринг компонентов через render().
  • Поиск элементов через queries: getByText, getByRole, queryByTestId.
  • Симуляция событий с помощью fireEvent или userEvent.
  • Асинхронные операции с waitFor и findBy.

Рендеринг компонентов Quasar

Quasar использует специфические компоненты с внутренней логикой и стилями. При рендеринге важно учитывать провайдеры и плагины. Для этого создаётся кастомная функция render:

import { render } from '@testing-library/vue';
import { Quasar } from 'quasar';
import MyComponent from 'src/components/MyComponent.vue';

const customRender = (component, options = {}) =>
  render(component, {
    global: {
      plugins: [Quasar],
    },
    ...options,
  });

// Использование
customRender(MyComponent);

Такой подход гарантирует корректную работу компонентов Quasar, включая диалоги, кнопки и форму ввода.

Поиск и взаимодействие с элементами

Поиск по тексту и ролям:

const { getByText, getByRole } = customRender(MyComponent);
const button = getByRole('button', { name: /отправить/i });

Тестирование ввода и событий:

import { fireEvent } from '@testing-library/vue';

const input = getByRole('textbox');
await fireEvent.update(input, 'тестовое значение');

const button = getByRole('button', { name: /сохранить/i });
await fireEvent.click(button);

Для более сложного взаимодействия рекомендуется использовать userEvent, который имитирует поведение пользователя с задержками и последовательностью действий.

Асинхронные операции и ожидания

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

import { waitFor } from '@testing-library/vue';

await waitFor(() => {
  expect(getByText('Данные загружены')).toBeInTheDocument();
});

findBy и findAllBy объединяют поиск и ожидание:

const message = await findByText('Успешно сохранено');

Работа с компонентами Quasar UI

Quasar имеет ряд компонентов с нестандартной разметкой: QDialog, QMenu, QTable. При тестировании этих компонентов важно учитывать:

  • QDialog и teleport – рендерятся в body, поэтому искать элементы нужно глобально.
  • QTable – данные могут рендериться динамически, использовать findAllByRole('row').
  • QMenu – открывается через событие click, тест должен сначала инициировать открытие меню.

Пример теста QDialog:

const { getByRole, queryByText } = customRender(MyComponent);

expect(queryByText('Подтвердить действие')).not.toBeInTheDocument();

const openButton = getByRole('button', { name: /открыть диалог/i });
await fireEvent.click(openButton);

expect(getByText('Подтвердить действие')).toBeVisible();

Организация тестов и лучшие практики

  • Каждый компонент тестировать отдельно, избегая зависимости от внешнего состояния.
  • Использовать mock для API или Vuex/Pinia состояния.
  • Придерживаться принципа «тестировать поведение, а не реализацию».
  • Проверять взаимодействие пользователя: клики, ввод, навигацию, видимость элементов.
  • Для сложных компонентов с асинхронной логикой использовать waitFor вместо setTimeout.

Примеры интеграционных тестов Quasar

Интеграционные тесты проверяют не только один компонент, но и его взаимодействие с другими:

const { getByRole, findByText } = customRender(MainPage, {
  global: {
    plugins: [Quasar],
  },
});

const addButton = getByRole('button', { name: /добавить/i });
await fireEvent.click(addButton);

const successMessage = await findByText('Элемент добавлен');
expect(successMessage).toBeVisible();

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

Полезные утилиты Testing Library

  • screen – глобальный доступ к DOM, сокращает destructuring.
  • within – локальный поиск внутри контейнера.
  • waitForElementToBeRemoved – ожидание исчезновения элемента.
  • jest-dom matchers: toBeVisible, toHaveTextContent, toHaveClass.

Эти инструменты делают тесты читаемыми и поддерживаемыми даже при сложной структуре Quasar-приложения.