Hint
Test behavior from the user's perspective — query by role/label/text, not by class or test ID
React Testing Library (RTL) is built around one guiding principle: "The more your tests resemble the way your software is used, the more confidence they can give you."
Query priority (use in this order):
getByRole — best, mirrors what screen readers seegetByLabelText — form inputs by their labelgetByText — visible text contentgetByTestId — last resort onlyimport { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
test('increments counter when button is clicked', async () => {
const user = userEvent.setup();
render( );
// Query by role — accessible, matches what users see
const button = screen.getByRole('button', { name: /increment/i });
const count = screen.getByText('0');
await user.click(button);
expect(screen.getByText('1')).toBeInTheDocument();
});
test('shows error for invalid email', async () => {
const user = userEvent.setup();
render( );
await user.type(screen.getByLabelText(/email/i), 'not-an-email');
await user.click(screen.getByRole('button', { name: /submit/i }));
expect(screen.getByText(/invalid email/i)).toBeInTheDocument();
});