Testing Pyramid: many unit tests, fewer integration tests, and minimal E2E tests. Each level catches different types of bugs.
Vitest is fast and Jest-compatible. React Testing Library tests components like users interact with them — by querying role, label, and text.
Unit test individual functions and hooks. Integration test component trees with mocked APIs. E2E tests (Playwright, Cypress) verify full user flows.
Test behavior, not implementation. Query by role first: screen.getByRole('button', { name: 'Submit' }). Avoid testing internal state or private methods.
Mock external dependencies: API calls, localStorage, timers. Use MSW (Mock Service Worker) for realistic API mocking. Snapshot tests catch unexpected UI changes.
Write tests that give confidence to refactor. If a test breaks when behavior is unchanged, it is too tightly coupled to implementation.