3.5 KiB
Frontend testing
Выбор проверки
Читай при изменении тестов или behavior с testing risk. Выбирай boundary по наблюдаемому исходу, а не внутреннему helper/component state.
| Изменение | Дешёвая надёжная проверка |
|---|---|
| Чистое domain преобразование/денежный расчёт | Unit case с граничными значениями |
| Форма, route access, recovery, UI-state selection | RTL component/route test через видимое поведение |
| Headers, refresh/retry, query invalidation | MSW на transport boundary |
| Только declarative props/Storybook fixture | Type/build + semantic/visual review; unit test без собственной логики не нужен |
Tests colocated с source (*.test.tsx для UI, существующий *.test.ts для pure code).
Arrange/Act/Assert, semantic queries (getByRole, label); test id — когда
пользовательский selector не выражает нужный элемент. Не тестируй Mantine/React
internals, private calls или passthrough wrapper ради coverage.
Инструменты и isolation
Используй fireEvent из объявленного @testing-library/react и ожидай async
outcome через findBy*/waitFor. user-event доступен транзитивно через Storybook,
но не принят как direct dependency; не добавляй его ради старого Markdown.
MSW запускается только Vitest setup в src/test/, без browser worker/mock dev mode.
Проверяй сеть MSW handlers, а не mock внутренностей query client или реальный backend.
Независимый case получает свой createTestQueryClient; rerender сохраняет
экземпляр и seeded cache. Providers выбирай явно. Existing teardown выполняет
RTL cleanup, auth reset и MSW reset: test client.
Важные случаи
Форма: field errors, отсутствие request при invalid input, submit blocking, сохранение ввода при network error. Routes: доступ/redirect и neutral auth bootstrap. Finance: loading/error/empty/loaded, cached snapshot при refetch failure, retry, отсутствие старых данных после session/connection switch. ErrorBoundary: test-only throwing route, безопасная ссылка и reset после navigation.
Примеры: AuthForm test, client test, usePortfolio test. Не копируй fixtures/сценарии целиком, если задача затрагивает один исход.
Команды
Итерация: npm run test:run -- <path> без coverage. Полный npm run verify
запускает Vitest один раз через test:coverage. Coverage floors — anti-regression
constraint, не повод тестировать декларации. После UI изменения отдельно
проверь доступность/визуальные состояния, которых JSDOM не доказывает.