Testing Standards
Unit testing patterns with Vitest and React Testing Library.
Testing Standards
Test Structure
import { render, screen } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { Button } from './Button';
describe('Button', () => {
it('renders correctly', () => {
render(<Button>Click me</Button>);
expect(screen.getByRole('button')).toHaveTextContent('Click me');
});
it('applies variant class', () => {
render(<Button variant="primary">Primary</Button>);
expect(screen.getByRole('button')).toBeInTheDocument();
});
it('handles click events', async () => {
const handleClick = vi.fn();
render(<Button onClick={handleClick}>Click</Button>);
await userEvent.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalledOnce();
});
});
Query Priority
Use queries in this order of preference:
getByRole- Most accessiblegetByLabelText- Form elementsgetByPlaceholderText- Input placeholdersgetByText- Non-interactive textgetByTestId- Last resort
User Interactions
import userEvent from '@testing-library/user-event';
it('handles user input', async () => {
render(<Input label="Email" />);
const input = screen.getByLabelText('Email');
await userEvent.type(input, 'test@example.com');
expect(input).toHaveValue('test@example.com');
});
Async Testing
import { waitFor } from '@testing-library/react';
it('loads data asynchronously', async () => {
render(<DataComponent />);
// Wait for loading to complete
await waitFor(() => {
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
});
expect(screen.getByText('Data loaded')).toBeInTheDocument();
});
Testing Hooks
import { renderHook, act } from '@testing-library/react';
import { useCounter } from './useCounter';
describe('useCounter', () => {
it('increments count', () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
});
Running Tests
# Run all tests
npm test
# Run once (CI mode)
npm run test:run
# Run with coverage
npm run test:coverage
# Run specific file
npx vitest Button.test.tsx