Contact

What is End-to-End Testing (E2E)?

Definition

End-to-end testing (E2E) is automated testing that exercises an application the way a real user does, with every layer from the interface down to the database running together. A test runner opens a browser, navigates pages, clicks buttons, fills in forms and checks what finally appears on screen. It gives the most realistic evidence that components are wired together correctly, but E2E tests are the slowest and hardest to maintain.

Also known as: E2E testing, E2E tests, end-to-end tests

End-to-end test driving a real browser like a user: visiting the cart, filling the form, paying and asserting the final result

Walking the whole user journey

A unit test isolates one function. An end-to-end test isolates nothing. A real browser, usually headless, loads the real front end; the front end calls the real back end; the back end writes to a test database. The test fails if any link in that chain is broken: a wrong API URL, a missing database migration, a misconfigured CORS rule, a button that moved behind a modal.

Playwright, Cypress and Selenium are the most widely used tools. This Playwright test checks that a guest shopper can add a product to the basket and reach checkout:

import { test, expect } from "@playwright/test";

test("guest can reach checkout", async ({ page }) => {
  await page.goto("/products/coffee-grinder");
  await page.getByRole("button", { name: "Add to basket" }).click();
  await page.getByRole("link", { name: "Basket" }).click();
  await expect(page.getByText("Coffee Grinder")).toBeVisible();
  await page.getByRole("button", { name: "Go to checkout" }).click();
  await expect(page).toHaveURL(/\/checkout/);
});

Locating elements by role and accessible name rather than by CSS class is deliberate. Class names change with every redesign; to the user, the “Add to basket” button stays the same.

The test pyramid

The test pyramid is a model for how to distribute automated tests: a broad base of unit tests, fewer integration tests in the middle, and a small number of end-to-end tests at the top.

LayerTypical countRun timeWhat a failure tells you
UnitHundreds to thousandsMillisecondsExactly which function broke
IntegrationTens to hundredsSecondsWhich two parts disagree
End-to-endA handful to a few dozenSeconds to minutesThat a user journey is broken, often not why

The inverted version, sometimes called the ice-cream cone, has most coverage written as browser tests and few unit tests underneath. Such a suite takes half an hour, fails for no obvious reason, and when it does fail someone still has to debug by hand to find the cause. Keep E2E tests for business-critical journeys and test detailed rule combinations further down the pyramid.

Flaky tests and how they happen

A flaky test passes and fails on the same code. End-to-end suites are the most exposed because they depend on many moving parts: network, browser, timing and shared data. The usual causes:

  • Fixed sleeps: “wait two seconds” is wasted time on a fast laptop and not enough on a busy CI runner. Use assertions that wait automatically until the element is ready.
  • Shared test data: if two tests modify the same account, the outcome depends on execution order. Each test should create and clean up its own data.
  • Third-party services: real payment, maps or email providers are outside the test's control; use their sandbox modes or stand-ins.
  • Animations and loading states: clicking a button that is still sliding into place can hit the wrong element.

Automatic retries hide flakiness rather than fix it. Report tests that only pass on retry, quarantine the worst offenders until they are fixed, and track the flaky rate over time. Otherwise the team learns to shrug at red builds (“it's that test again”), and one day a real regression gets the same shrug.

When and where E2E suites run

End-to-end tests usually run in the CI/CD pipeline after the application has been deployed to a production-like staging environment; a failure stops the release. A short smoke suite that exercises a few critical paths straight after a production deploy is also common. Running the same scripted journeys against production on a schedule is no longer testing but synthetic monitoring, which helps you notice an outage before customers do.

Deciding which journeys deserve E2E coverage comes down to one question: if this breaks, do we lose money, customers or data? Sign-in, registration, basket and checkout, quote request forms and password reset usually top the list.

Related terms

← Back to the glossary