The default way to run tests is in watch mode, which automatically re-runs tests when files change:
cd clientnpm test
This will start Jest in watch mode:
PASS src/App.test.js ✓ renders learn react link (24 ms)Test Suites: 1 passed, 1 totalTests: 1 passed, 1 totalSnapshots: 0 totalTime: 1.234 sRan all test suites related to changed files.Watch Usage › Press a to run all tests. › Press f to run only failed tests. › Press q to quit watch mode. › Press p to filter by a filename regex pattern. › Press t to filter by a test name regex pattern. › Press Enter to trigger a test run.
The client/src/setupTests.js file runs before each test:
client/src/setupTests.js
// jest-dom adds custom jest matchers for asserting on DOM nodes.// allows you to do things like:// expect(element).toHaveTextContent(/react/i)// learn more: https://github.com/testing-library/jest-domimport '@testing-library/jest-dom';
This imports jest-dom matchers, giving you access to useful assertions like:
Create a file next to your component with the .test.js extension:
src/ ├── MyComponent.js └── MyComponent.test.js
Or use the .spec.js extension - both work with Create React App.
2
Import testing utilities
import { render, screen, fireEvent } from '@testing-library/react';import userEvent from '@testing-library/user-event';import MyComponent from './MyComponent';
// Good - tests user-visible behaviortest('shows error message on failed login', async () => { render(<LoginForm />); // ... trigger failed login ... expect(screen.getByText(/invalid credentials/i)).toBeInTheDocument();});// Avoid - tests internal statetest('sets error state to true', () => { const { result } = renderHook(() => useAuth()); // Testing internal state});
Use async utilities for async operations
Wait for elements to appear using async queries:
import { render, screen, waitFor } from '@testing-library/react';test('loads and displays data', async () => { render(<DataComponent />); // Wait for element to appear const data = await screen.findByText(/loaded data/i); expect(data).toBeInTheDocument(); // Or use waitFor for complex assertions await waitFor(() => { expect(screen.getByText(/status: complete/i)).toBeInTheDocument(); });});