Стратегия тестирования и отлова ошибок
Контекст
Для обеспечения качества frontend-приложений необходима комплексная стратегия тестирования, охватывающая все уровни: от unit-тестов до мониторинга ошибок в production.
Текущая ситуация:
- Отсутствует единый подход к тестированию
- Нет автоматического отслеживания регрессий
- Ошибки в production обнаруживаются пользователями
Требования:
- Покрытие всех уровней тестирования
- Автоматизация в CI/CD
- Мониторинг production-ошибок
- Визуальное тестирование компонентов
- Отслеживание производительности
Решение
Внедрить многоуровневую стратегию тестирования на уровне каждого проекта и модуля.
Стек тестирования
| Уровень | Инструмент | Назначение |
|---|---|---|
| Unit | Vitest | Тестирование функций, composables, stores |
| Component | Storybook + Chromatic | Визуальное тестирование, документация компонентов |
| E2E | Cypress Studio | End-to-end сценарии |
| Load | Artillery | Нагрузочное тестирование |
| Performance | Unlighthouse | Отслеживание регресса производительности |
| Errors | Sentry | Мониторинг ошибок в production |
Обоснование
Unit: Vitest
| Альтернатива | Плюсы | Минусы |
|---|---|---|
| Jest | Популярный, много документации | Медленный, сложная настройка с Vite |
| Vitest | Нативная интеграция с Vite/Nuxt, быстрый, совместимый API | Менее зрелый |
Выбор: Vitest — нативная интеграция с Nuxt, одна конфигурация с проектом.
Документация: https://vitest.dev/
Component: Storybook + Chromatic
| Альтернатива | Плюсы | Минусы |
|---|---|---|
| Histoire | Нативный для Vue | Менее развитая экосистема |
| Storybook | Стандарт индустрии, богатая экосистема | Сложнее настройка |
| Chromatic | Автоматический visual diff, интеграция со Storybook | Платный для больших команд |
Выбор: Storybook для документации + Chromatic для visual regression testing.
Документация:
E2E: Cypress Studio
| Альтернатива | Плюсы | Минусы |
|---|---|---|
| Playwright | Быстрый, multi-browser | Меньше визуальных инструментов |
| Cypress | Отличный DX, Cypress Studio для записи тестов | Только Chromium по умолчанию |
Выбор: Cypress с Cypress Studio — возможность записи тестов без кода, отличный debugging.
Документация: https://docs.cypress.io/
Load: Artillery
| Альтернатива | Плюсы | Минусы |
|---|---|---|
| k6 | Мощный, Go-based | Требует изучения |
| Artillery | Простой YAML-конфиг, Node.js экосистема | Менее мощный для сложных сценариев |
| Locust | Python, гибкий | Другой стек |
Выбор: Artillery — простота конфигурации, интеграция с Node.js проектами.
Документация: https://www.artillery.io/
Performance: Unlighthouse
| Альтернатива | Плюсы | Минусы |
|---|---|---|
| Lighthouse CI | Официальный Google | Сложная настройка |
| Unlighthouse | Сканирует весь сайт, простой отчёт | Менее гибкий |
| SpeedCurve | Профессиональный мониторинг | Платный |
Выбор: Unlighthouse — автоматическое сканирование всех страниц, интеграция в CI.
Документация: https://unlighthouse.dev/
Errors: Sentry
| Альтернатива | Плюсы | Минусы |
|---|---|---|
| Sentry | Стандарт индустрии, богатый функционал | Платный для больших объёмов |
| Bugsnag | Хороший UX | Дороже |
| LogRocket | Session replay | Очень дорогой |
Выбор: Sentry — стандарт индустрии, отличная интеграция с Vue/Nuxt.
Документация: https://docs.sentry.io/platforms/javascript/guides/vue/
Архитектура тестирования
Пирамида тестов
/\
/ \ E2E (Cypress)
/----\ Критические user flows
/ \
/--------\ Component (Storybook + Chromatic)
/ \ Визуальные регрессии
/------------\
/ \ Unit (Vitest)
/________________\ Логика, utils, composables
Что тестировать на каждом уровне
| Уровень | Что тестировать | Пример |
|---|---|---|
| Unit | Чистые функции, composables, store actions | formatCurrency(), useOrders() |
| Component | Визуал компонентов, состояния | OrderCard в разных состояниях |
| E2E | Критические user flows | Авторизация, создание заказа |
| Load | API endpoints под нагрузкой | 100 concurrent users |
| Performance | Core Web Vitals | LCP, FID, CLS |
Структура в проекте
app-name/
├── app/
│ └── components/
│ └── OrderCard/
│ ├── OrderCard.vue
│ ├── OrderCard.stories.ts # Storybook
│ └── OrderCard.test.ts # Vitest
├── tests/
│ ├── e2e/ # Cypress
│ │ ├── auth.cy.ts
│ │ └── orders.cy.ts
│ ├── load/ # Artillery
│ │ └── api-load.yml
│ └── setup.ts # Vitest setup
├── .storybook/ # Storybook config
├── cypress.config.ts
├── vitest.config.ts
└── unlighthouse.config.ts
CI/CD интеграция
Pipeline stages
# .gitlab-ci.yml / .github/workflows/ci.yml
stages:
- lint
- test
- visual
- e2e
- performance
- deploy
unit-tests:
stage: test
script:
- pnpm test:unit
storybook-build:
stage: visual
script:
- pnpm storybook:build
- pnpm chromatic --project-token=$CHROMATIC_TOKEN
e2e-tests:
stage: e2e
script:
- pnpm test:e2e
performance:
stage: performance
script:
- pnpm unlighthouse
only:
- main
Когда запускать
| Тест | PR | Main | Nightly |
|---|---|---|---|
| Unit (Vitest) | ✅ | ✅ | ✅ |
| Visual (Chromatic) | ✅ | ✅ | - |
| E2E (Cypress) | ✅ | ✅ | ✅ |
| Load (Artillery) | - | - | ✅ |
| Performance (Unlighthouse) | - | ✅ | ✅ |
Sentry интеграция
Настройка
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@sentry/nuxt/module'],
sentry: {
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
},
})
Что отслеживать
- JavaScript errors
- Unhandled promise rejections
- API errors (4xx, 5xx)
- Performance transactions
- User feedback
Source Maps
// nuxt.config.ts
export default defineNuxtConfig({
sourcemap: {
client: true,
},
sentry: {
uploadSourcemaps: true,
},
})
Последствия
Положительные
- Раннее обнаружение багов
- Автоматическое отслеживание визуальных регрессий
- Мониторинг production-ошибок в реальном времени
- Контроль производительности
- Документация компонентов через Storybook
- Уверенность при рефакторинге
Отрицательные
- Время на написание и поддержку тестов
- Дополнительная инфраструктура (Chromatic, Sentry)
- Увеличение времени CI/CD pipeline
- Требуется обучение команды
Coverage требования
Минимальные пороги
| Метрика | Порог |
|---|---|
| Unit coverage | 60% |
| Component coverage (Storybook) | Все shared компоненты |
| E2E coverage | Критические flows |
| Lighthouse score | > 80 |
Приоритеты покрытия
- Обязательно: composables, utils, stores
- Обязательно: shared компоненты (UI layer)
- Обязательно: критические user flows (auth, core actions)
- Желательно: page components
- Желательно: edge cases