QA · Read 7 min

End-to-end (E2E) tests: exercising the user’s entire journey

They mimic a real person doing the task from start to finish. They are the most realistic and the most expensive to maintain, which is exactly why they should not be the majority.

An end-to-end (E2E) test does what a real person would do while using your product: it opens the application, types the password, clicks the button, waits for the response and confirms the result is correct, from start to finish. It does not look at a lone function or an isolated module: it walks the whole path, with the database running, the network in the middle and the interface responding. It is the test that most closely resembles the truth. And for that very reason it is the slowest and the most fragile of all.

That is the tension that defines E2E tests, and the one you must understand before writing your first. They give a confidence no other test gives, because they validate the system exactly as the user experiences it. But each one is expensive to write, slow to run and prone to breaking for reasons that have nothing to do with a real bug. Holding that tension, without tipping into either extreme, is what separates a healthy test suite from one the whole team ends up hating.

01 · the whole pathWhat an E2E test really checks

An E2E test verifies an entire user flow across every layer of the system, just as it would happen in production. Think of your product's most critical flow: a new user signs up, confirms their email, logs in and creates their first item. An E2E test runs that whole journey, with no shortcuts, and fails if anything breaks at any point along the way.

The difference from a unit test is one of altitude. The unit test looks at an isolated piece: a function that computes a total, with no database and no screen. The E2E test looks at the whole building in motion: the click in the browser, the request traveling across the network, the server processing it, the database saving the data and the screen confirming it. If the unit test asks "is this piece well built?", the E2E test asks "can the user do what they came to do?".

The unit test validates a piece. The E2E test validates that the user reaches their goal.

This is its irreplaceable virtue: an E2E test that passes tells you the critical path truly works, with all the parts connected. No lower-level test gives you that guarantee, because each one lives in its own bubble. The pieces can be perfect on their own and still fail to fit together. The E2E test is the only one that verifies the real fit.

Figure 1 · an E2E test walks every layer
Browser Network Server Database E2E test: walks the whole path Unit
The E2E test (green bar) crosses all four layers, just like the user. The unit test (amber bar) touches a single function inside the server. An integration test would sit in between: two or three layers, not all of them.

02 · the billWhy they are the most expensive to maintain

E2E tests are expensive for three concrete reasons, and it is worth naming them plainly because they are the key to using them well.

They are slow. Every E2E test boots the real system: it launches a browser, waits for screens to load, makes genuine network requests, writes and reads from a database. Where a unit test takes milliseconds, an E2E test takes seconds, sometimes tens of seconds. Multiply that by hundreds of cases and your suite goes from running in the blink of an eye to taking half an hour. A slow suite is a suite the team stops running, and a test that is not run protects nothing.

They are fragile. Because they depend on everything, anything can break them. A button that changed its name, an animation that takes a bit longer, an external service having a bad day, test data left dirty. The E2E test fails, but often it does not fail because of a real bug: it fails because of the environment. Those intermittent failures are called "flaky" tests, and they are poison for the team's confidence. When a test fails at random, people learn to ignore the red light, and that is precisely the day the red light was flagging a real problem.

A test that fails at random does not protect: it teaches the team to ignore the alarm.

When they fail, they do not say where. A unit test that fails points at the guilty function with surgical precision. An E2E test that fails only tells you that "sign-up did not work". Was it the interface? The network? The server? The database? The diagnosis takes detective work, and that work costs time every single time. The E2E test warns you there is a fire, but it does not tell you which room.

Fast, realistic, cheap: pick two

No test is all three at once. The unit test is fast and cheap, but not very realistic: it tests pieces, not the system. The E2E test is realistic, but slow and expensive. There is no perfect test; there is a proper mix. The whole art of testing lies in distributing the effort across levels according to what each one gives and what it costs.

03 · few and well chosenWhy they should not be the majority

Out of the earlier tension comes the practical rule: E2E tests should be few and reserved for what truly matters. Not because they are bad, but because their cost is only justified on the paths you cannot afford to have break.

The right question when writing an E2E test is not "can this be tested end to end?" but "is this flow so critical that I need the most realistic guarantee possible, and am I willing to pay the slowness and fragility it brings?". For sign-up, login, payment or your product's core flow, the answer is yes without hesitation: if that breaks, the business grinds to a halt. For a secondary button or an edge case of validation, the answer is almost always no: that is better and more cheaply covered by a lower-level test.

This idea has a shape, and the shape is a pyramid. At the base go many unit tests, fast and cheap, covering the bulk of the logic. In the middle, a smaller amount of integration tests, verifying that the pieces talk to each other. And at the top, a few E2E tests, carefully chosen, validating the flows that admit no failure. The pyramid shape is not an aesthetic whim: it is the direct consequence of each level having a different cost. Putting many E2E tests at the base would be like paying gold prices for what ordinary material resolves.

Figure 2 · the pyramid: many cheap ones below, few expensive ones above
E2E (few) Integration Unit (many) slow, expensive fast, cheap
The width of each layer is its quantity; the height, its cost per test. E2E tests crown the pyramid precisely because they are the most expensive: they are used sparingly and only where their realism is worth what it costs.

04 · in practiceHow to live with the expensive without suffering it

Accepting that E2E tests are expensive does not mean resigning yourself to them hurting. There is a handful of habits that keep the suite useful instead of turning it into a burden.

The first is to be ruthless when choosing what deserves an E2E test. Every test you add to the top is a debt you will pay on every run, on every interface change and on every intermittent failure. If a case can live one level down, move it down. The top is exclusive territory for critical flows.

The second is to treat fragility as a defect, not as something normal. An E2E test that fails at random must be fixed or deleted, never tolerated. Stabilizing means waiting for real conditions instead of fixed timings, isolating each test's data and not depending on unpredictable external services. A small, reliable suite is worth infinitely more than a large one no one believes in.

The third is to read the E2E test for what it is: the last line of defense, not the first. When an E2E test catches a bug, it almost always means something slipped past the levels below. The lesson is not "I need more E2E tests" but "what cheaper test should I have had to catch this sooner?". Used that way, the E2E test not only protects the critical flow: it also reveals where the rest of your safety net is weak.

In the end, the E2E test is the one that most resembles your user and, for that reason, the one that gives the most confidence when it passes. Its price (slowness, fragility, hard diagnosis) is not a reason to avoid it, but to use it with precision. Few, well chosen and well cared for, they crown a healthy testing strategy. Many and neglected, they sink it. The difference is not in the tool: it is in knowing exactly which paths deserve to be walked in full.

Sources

  1. ISTQB (International Software Testing Qualifications Board). Certified Tester Foundation Level (CTFL) Syllabus, v4.0 (2023). Defines the test levels (component, integration, system, acceptance) and the role of end-to-end system and acceptance testing. istqb.org.
  2. ISO/IEC 25010:2011. Systems and software engineering. Systems and software Quality Requirements and Evaluation (SQuaRE). System and software quality models. Quality model underpinning which characteristics (functionality, reliability, usability) full system tests verify. iso.org.
  3. Cohn, M. (2009). Succeeding with Agile: Software Development Using Scrum. Addison-Wesley. Chapter on test automation: origin of the test pyramid and the cost-per-level argument.
  4. Fowler, M. (2012). TestPyramid. martinfowler.com/bliki/TestPyramid.html. Explains why end-to-end UI tests should be few because of their cost and "flakiness".

Learn more about AI

See all Learn AI