Vitest has eaten Jest's lunch — it's faster, works with Vite natively, and has better TypeScript support out of the box. This skill gives your AI agent the patterns to write React component tests that test behavior, not implementation — the kind that catch real bugs and don't break when you refactor.
**Bottom line:** If your agent is touching React code, it needs to know how to write tests the right way. This skill is the blueprint.
npm install -D vitest @testing-library/react @testing-library/user-event jsdom @vitejs/plugin-react
// vitest.config.js
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['./src/test/setup.js']
}
});
import { render, screen, userEvent } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { LoginForm } from './LoginForm';
describe('LoginForm', () => {
it('submits email and password on submit', async () => {
const onSubmit = vi.fn();
render(<LoginForm onSubmit={onSubmit} />);
await userEvent.type(screen.getByLabelText(/email/i), 'test@example.com');
await userEvent.type(screen.getByLabelText(/password/i), 'secret123');
await userEvent.click(screen.getByRole('button', { name: /sign in/i }));
expect(onSubmit).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'secret123'
});
});
});
| Pros | Cons |
|---|---|
| Tests mirror how users actually interact with your UI | Requires understanding of RTL query priorities |
| MSW mocks are realistic and survive refactors | Still some setup overhead for complex async |
|---|
| Vitest is noticeably faster than Jest | jsdom doesn't perfectly replicate browser behavior |
|---|
| Great DX — watch mode, useful error messages | Component tests can be brittle without good abstractions |
|---|