End-to-end testing
End-to-End Testing: The Complete Guide
What end-to-end testing is, where it fits alongside unit and integration tests, what to cover, why E2E tests get flaky and how to fix it, and how to choose a tool.
End-to-end testing is where you find out whether the pieces actually fit together. Unit and integration tests can all pass while the sign-up button does nothing, because no unit test drives the sign-up button. This guide covers what to test end to end, how to keep those tests from becoming a liability, and how the tooling has changed.
What is end-to-end testing?
End-to-end (E2E) testing verifies a complete user journey through the running application from the outside — typically a real browser driving the real UI against a real (or realistic) backend. Where a unit test asks "does this function return the right value," an E2E test asks "can a user actually sign up, get a confirmation email, and land on the dashboard." It's the closest automated proxy for real use, and the most expensive kind of test to write and run.
Where E2E sits: the testing pyramid
| Layer | How many | Speed | What it proves |
|---|---|---|---|
| Unit | Hundreds–thousands | Milliseconds | Each piece of logic is correct |
| Integration | Dozens–hundreds | Seconds | Pieces are wired together correctly |
| End-to-end | A handful (scripted) | Seconds–minutes | The whole thing works for a user |
The pyramid's logic is that E2E tests are costly, so you want just enough to be confident. That advice was written when integration tests were painful and there was no such thing as unscripted coverage — The Testing Pyramid, and Where It Breaks Down covers how the model has aged, and the testing vocabulary post defines the terms.
What to cover with end-to-end tests
Prioritise critical user journeys — the flows where failure is a genuine problem:
- Sign-up, login, password reset, and other authentication paths.
- The core loop of your product: creating, editing, and deleting the main object it's built around.
- Checkout or any money-handling flow.
- Onboarding, if a broken step means a user never activates.
- Anything that has broken before and mattered.
You don't need an E2E test for every screen. You need one for every journey you'd be embarrassed to ship broken.
What makes a good end-to-end test
- It tests a journey, not a page. "User completes checkout," not "the checkout page renders."
- It asserts the outcome that matters. Don't just check that steps completed — check that the order exists, the email was queued, the balance changed.
- It's independent. It sets up its own data and doesn't depend on another test running first.
- It fails for one reason. When it goes red, it should point at a specific step, not a vague "the flow is broken."
- It's stable. If it fails randomly, it has negative value — people learn to ignore it.
The flakiness problem — causes and fixes
Flaky E2E tests are the main reason teams lose faith in their suites. The usual causes and their fixes:
| Cause | Fix |
|---|---|
| Timing — the test acts before the app is ready | Wait on application state (an element, a network response), never a fixed sleep |
| Test-order dependence | Each test sets up and tears down its own state |
| Shared mutable data | Isolated data per test run; a dedicated test account |
| Brittle selectors | Identify elements by role or accessible name, not a fragile CSS path |
| Third-party dependencies | Stub them, or accept and retry known-noisy external calls |
Autonomous tools sidestep the selector and timing causes structurally: there's no fixed script racing the app, because the tool re-derives how to reach each page at run time. Genuinely non-deterministic app behaviour still shows up as a finding.
Test data, authentication, and environments
- Data. E2E tests need known starting state. Seed it programmatically or reset it between runs; don't rely on data that happens to be there.
- Authentication. Log in through the real flow at least once to keep it covered, then reuse the session for other tests. Support for magic links, SSO, and 2FA varies by tool.
- Environments. Run against a staging environment that mirrors production, with a dedicated test account — E2E tests click real buttons, including destructive ones.
End-to-end testing tools
| Type | Examples | Trade-off |
|---|---|---|
| Frameworks | Playwright, Cypress, Selenium | Full control and exact assertions; you write and maintain the suite |
| Codeless recorders | Testim, mabl, Reflect, Autify | No code; still an owned, recorded suite to maintain |
| Autonomous agents | Manta | No suite to write or maintain; broad behavioural coverage rather than exact per-step assertions |
| Managed services | QA Wolf | Someone else writes and maintains the suite; priced as a service |
The comparison pages work through these tool by tool — for example Manta vs Playwright for the managed-vs-DIY decision — and the autonomous testing guide covers how unscripted coverage fits alongside a small framework suite. Autonomous Testing vs. Scripted Tests is the shorter version of that argument.
Running E2E tests in CI
Scripted E2E suites usually run on merges to the main branch and before releases rather than on every pull request, because they're slow. Parallelise across machines to keep the wall-clock time reasonable. Autonomous runs fit the same slots — on a merge, on a schedule, or on a deploy to staging — and don't need the parallelisation plumbing.
How much end-to-end testing is enough
Enough to cover every journey you'd be unwilling to ship broken, and no more scripted tests than your team will actually maintain. If that number is small, cover the rest with autonomous exploration rather than leaving it uncovered. The failure mode isn't "too few E2E tests" — it's a large brittle suite that everyone ignores.
Key takeaways
- E2E tests verify journeys through the running system — the thing unit and integration tests can't see.
- Cover critical user journeys; don't test every screen.
- Flakiness kills suites. Wait on state, isolate data, select by role.
- Keep the scripted suite small; use autonomous coverage for breadth.
- Run it in CI, against a production-like staging environment with a dedicated account.
Frequently asked questions
Try autonomous testing on your app
Point Manta at a URL and see what it finds — no scripts, no setup. Free, no credit card.