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

↑ 5.7 Тестирование приложения · ← Предыдущая · → Следующая

Обязательно~4 мин чтенияУровень: middle

Зачем это на собесе

Компоненты Quasar требуют плагина и имеют особенности рендера (порталы, диалоги, меню).

Объяснение

Официальный пакет @quasar/quasar-app-extension-testing-unit-vitest (или ручная настройка): плагин Quasar и глобальные настройки в setup-файле.

// vitest.config.ts
export default defineConfig({ plugins: [vue({ template: { transformAssetUrls } }), quasar({ sassVariables: "src/css/quasar.variables.scss" })],
  test: { environment: "jsdom", globals: true, setupFiles: ["test/setup.ts"], css: false } });
 
// test/setup.ts
import { installQuasarPlugin } from "@quasar/quasar-app-extension-testing-unit-vitest";
import { Notify, Dialog } from "quasar";
installQuasarPlugin({ plugins: { Notify, Dialog } });        // глобальная установка Quasar для всех тестов
import { mount } from "@vue/test-utils";
import { render, screen } from "@testing-library/vue";
 
it("QInput показывает ошибку валидации", async () => {
  const user = userEvent.setup();
  render(OrderForm, { global: { plugins: [pinia] } });
  await user.click(screen.getByRole("button", { name: /сохранить/i }));
  expect(await screen.findByText("Обязательное поле")).toBeInTheDocument();
});
 
it("уведомление вызывается", async () => {
  const notify = vi.spyOn(Notify, "create");                  // проверка вызова плагина
  await mountAndSubmit();
  expect(notify).toHaveBeenCalledWith(expect.objectContaining({ type: "positive" }));
});

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

ПроблемаРешение
Порталы: QDialog, QMenu, QSelect-меню рендерятся в bodyscreen/document.body (Testing Library), attachTo, findComponent
Анимации Transitionglobal.stubs: { transition: false } или отключить (quasar без анимаций в тестах)
QSelect: выбор опцииклик по полю → findByRole("option", ...) → клик
QTable серверная пагинацияэмиссия @request, проверка вызова API
$q в компонентахустановленный плагин или mocks: { $q }; useQuasar() возвращает реальный объект после installQuasarPlugin
Иконки и шрифтыне нужны (заглушки)
QForm.validate()await form.validate() внутри wrapper.vm/ref, либо через клик submit
Размер экрана$q.screen — переопределить в installQuasarPlugin/мокнуть
Дата/QDateфиксированные значения, фейковое время

Практика: тесты через доступные роли/подписи, а не классы .q-* (они меняются между версиями). Обёртки над Quasar-компонентами (см. Кастомизация и обёртки над компонентами Quasar) тестируются как пользовательский интерфейс.

Нюансы и подводные камни

  • Без installQuasarPlugin компоненты рендерятся с предупреждениями/ошибками.
  • Асинхронное поведение меню и диалогов: findBy…/waitFor.
  • Тесты, завязанные на классы q-*, ломаются при обновлении.
  • CSS в jsdom не считается: видимость элементов и layout недоступны.
  • Тяжёлые компоненты (QTable с большим набором данных) замедляют тесты.

Практика

  1. Настройте Vitest с Quasar и напишите тест формы с QInput/QSelect.
  2. Протестируйте QDialog подтверждения удаления.
  3. Проверьте вызов Notify после успешного сохранения.

Вопросы с ответами

Связанные темы