End-to-End Test
A test of the whole system through its real interface.
Also known as: E2E test, E2E tests, end to end testing, browser test, UI automation test
An end-to-end (E2E) test exercises the whole system the way a real user would, through the real interface: a browser clicking through your web app, or an API client calling a deployed service, with real (or realistic) databases and services behind it.
// Playwright
test("user can sign up and place an order", async ({ page }) => {
await page.goto("/signup");
await page.getByLabel("Email").fill("ana+e2e@example.com");
await page.getByLabel("Password").fill("correct-horse-battery");
await page.getByRole("button", { name: "Create account" }).click();
await page.getByRole("link", { name: "Kettle" }).click();
await page.getByRole("button", { name: "Add to cart" }).click();
await page.getByRole("button", { name: "Checkout" }).click();
await expect(page.getByText("Order confirmed")).toBeVisible();
});
Common tools: Playwright, Cypress, Selenium. For backend systems, E2E may mean sending a real request through the gateway and checking the full chain, including queues and databases.
What they’re good for
They give the highest confidence that the pieces really work together: routing, frontend, API, database, third-party integrations, configuration. They catch problems that unit and integration tests can’t see.
What they cost
- Slow (seconds to minutes each).
- Brittle: UI changes, timing and test data break them.
- Flaky: random failures from timing and shared state erode trust (flaky tests).
- Hard to debug: a failure could be anywhere in the stack.
- Expensive to maintain and to run.
So use few, and use them wisely
Keep a small number covering the critical user journeys (sign up, log in, checkout, the core money path). Test details at lower, faster levels (testing pyramid).
Making them reliable
- Wait for conditions, never for fixed sleeps (
await expect(...).toBeVisible(), notsleep(3000)). - Find elements by role, label or text, or by stable test IDs, not by fragile CSS paths (Testing Library philosophy).
- Create the data a test needs, itself, and clean up, so tests don’t depend on each other or on order.
- Run in an isolated, production-like environment, not on the live system.
- Quarantine or fix flaky tests quickly.
- Run them in CI, with screenshots and traces saved on failure.
- A fast smoke test after every deploy (smoke tests) is a minimal E2E check.