Contents

Engineering Craft › Testing

Component Testing

Testing a UI component in isolation with user-like interactions.

Also known as: UI component testing, React component testing, frontend component tests

A component test renders one UI component, on its own, and interacts with it the way a user would: clicking, typing, reading what’s on screen.

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { LoginForm } from "./LoginForm";

test("shows an error for an empty email", async () => {
  render(<LoginForm onSubmit={jest.fn()} />);

  await userEvent.click(screen.getByRole("button", { name: /sign in/i }));

  expect(screen.getByText(/email is required/i)).toBeInTheDocument();
});

What to test

  • What the user sees for given props or state (empty, loading, error, filled).
  • What happens when they interact: the right callback is called with the right data.
  • Conditional UI: disabled buttons, hidden sections.

What to avoid

  • Testing implementation details, such as internal state or class names. Those tests break when you refactor even though behavior is unchanged. Find elements as a user would, by role, label and text (see testing library philosophy).
  • Snapshot tests of everything. Big snapshots get approved without being read.
  • Real network calls. Replace them with a mock server or a stub.

Component tests sit between unit tests of functions and end-to-end tests of the whole app: faster than the browser, but more realistic than testing logic alone. They run in a simulated DOM (such as jsdom) or in a real browser, depending on the tool.