End-to-end testing
End-to-end testing walks a business process through the assembled system from start to finish, the way a customer would, in conditions close to production. The page opens with one shop’s whole suite — twelve journeys, the seam only each one proves, and what is real and what is replaced — then covers what no lower level can prove, the shapes a portfolio takes, what a red journey costs, how to choose journeys and keep them trustworthy, and three failures where a test stopped one step short.
- It proves
- The parts hold together
- Cost per case
- Highest of any test
- Right number
- Small, not zero
One shop’s end-to-end suite on one screen — twelve journeys, the seam each proves, and what is real
Nobody opens a page about end-to-end testing for the definition. They open it because a suite of four hundred browser tests takes an hour and fails every other run, or because someone asked how many such tests a team should have. Below is the whole end-to-end suite of the online shop whose smoke gate and regression suite the two neighbouring pages list. It has twelve journeys. Each row names the seam only that journey proves — a place where two real parts of the system meet and no lower test can reach — and says what is real and what is replaced. Later sections cite the journeys by number.
| # | Journey | The seam only it proves | Real, and replaced | Time |
|---|---|---|---|---|
| 1 | Search “blue jumper”, open SKU 30417, add it, pay with the test card, get an order number | Front end → checkout → payments → orders → queue → warehouse: the order arrives with every line and amount right (regression row 16) | Everything of the shop’s; the payment provider’s sandbox; the warehouse’s test endpoint | 90 s |
| 2 | Sign up, confirm the email, sign in, reload — still signed in. In Chromium and in WebKit | The session cookie through the CDN, the front end and accounts, in a real browser engine (regression row 3) | Real; the email provider’s test mode delivers to a test inbox | 2 × 60 s |
| 3 | Reset a forgotten password from the emailed link | A link built by accounts, carried by email, opened through the CDN’s redirect, accepted once | Real; test inbox | 45 s |
| 4 | Apply SPRING10, change the quantity, pay | The total on the screen is the amount the payment provider is asked to charge | Real; sandbox | 70 s |
| 5 | Pay with a card that needs 3-D Secure: out to the bank’s check and back | The redirect out of the shop and back into the same session and the same basket | Real; the sandbox’s challenge page | 80 s |
| 6 | A card is declined; pay again with a second card | The basket survives the decline, and exactly one order exists afterwards | Real; the sandbox’s decline card | 75 s |
| 7 | Ask the order assistant “where is my order” about an order the journey has just placed | Chat widget → assistant → get_order → orders, and the returned status on the screen | Real tools; the model’s replies replayed from a recording, as on Testing LLM products | 40 s |
| 8 | Start a return within 30 days; the returns label arrives by email | Returns → orders → email, with the label attached and readable | Real; the carrier’s label service replaced by a stub, whose shape a contract test checks | 60 s |
| 9 | The warehouse confirms the return arrived; the refund lands | A webhook from the warehouse → refund → payments → email, with the amount that was paid | Real; the test harness sends the warehouse’s webhook | 90 s |
| 10 | Change the delivery address after ordering, before dispatch | The new address reaches the warehouse before the order is picked | Real | 50 s |
| 11 | Check out as a guest, then create an account from the confirmation page | An anonymous basket and order become a customer’s, and appear in their order history | Real | 70 s |
| 12 | A support agent refunds a damaged item in the back office | The back office and the shop share orders and payments; an agent can refund, but cannot change a price | Real; the staff sign-in replaced by a test identity | 60 s |
What only an end-to-end test proves
The ISTQBInternational Software Testing Qualifications Board — testing certification bodyThe international body behind the most widely taken software-testing certifications, which also publishes a glossary of testing terms. Its definitions are a common reference in interviews and contracts; they fix vocabulary, not how a team has to work.All terms glossary defines end-to-end testing as “a test type in which business processes are tested from start to finish under production-like circumstances”. Two phrases in it carry the weight. “From start to finish” means the journey ends at the outcome a customer needs — the parcel in the warehouse, the money back on the card — not at the last screen. “Production-like” means the configuration, the routing and the topology of the real thing. Notice too that ISTQB calls it a test type, not a level. The test pyramid draws it as the top layer, but what defines it is what it covers, not which part of the code it sits in.
Every test below it works in a controlled setting. A unit test replaces its neighbours with fakes. An integration test uses a real database and a stand-in for the payment provider. A contract test proves two services agree about a message without either running the other. All of that is valuable, and none of it can show that the deployed system, with its real routing, real environment variables, real session handling and real front-end build, lets a person finish what they came to do. The classic defect that escapes a well-tested system is not a wrong calculation. It is a misconfigured redirect, a attribute that breaks the session in one browser, a feature flaga switch around new codeA switch that decides at run time whether a piece of code is active, so it can ship to production turned off and be turned on for a chosen audience later. It separates deploying from releasing, and it costs something: every live flag is a branch in the code that has to work in both states.Full article →All terms on in stagingthe rehearsal environmentA copy of production that changes are tried on before real users meet them. How much it proves depends entirely on how closely it matches production — a staging environment with a tenth of the data, no real traffic and a different config demonstrates that the code starts, and not much more.All terms and off in production. Each lives at a seam, and every lower test replaced exactly that seam.
The diagram is the mechanism behind every case at the end of this page. Split a journey into segments, test each segment with a stand-in at its joint, and every segment can be green while the journey fails — because the defect lives in the joint, and the joint is the one thing no segment test ran. Martin Fowler adds a warning about the words: teams “conflate the concepts of end-to-end tests, UIUser Interface — what the user seesEverything the user sees and operates: screens, buttons, fields, states. UI is how the interaction looks; whether the interaction makes sense in the first place is a UX question, and the two get confused constantly.All terms tests, and customer facing tests. These are all orthogonal characteristics.” A test that clicks through a browser against a mocked back end is a UI test. It is not end to end, and it cannot prove a seam it has replaced.
Pyramid, trophy, honeycomb — three shapes, one argument about cost
Mike Cohn described the test pyramid in his 2009 book Succeeding with Agile, and Martin Fowler’s 2012 note made it famous: many unit tests at the bottom, fewer service tests in the middle, few end-to-end tests at the top, because tests that run end to end through the interface are “brittle, expensive to write, and time consuming to run”. ISTQB’s glossary now has an entry for it. Since then other shapes have been drawn, each by people working on a different kind of system, and the table puts them side by side.
| Shape | From | Where the bulk is | End to end | Fits when |
|---|---|---|---|---|
| Pyramid | Mike Cohn, 2009; Martin Fowler, 2012 | Unit tests | Few, at the top | Most of the logic lives inside one codebase |
| 70 / 20 / 10 | Google Testing Blog, 2015 | 70% unit, 20% integration | 10%, “as a good first guess” | A team that needs a number to start from |
| Trophy | Kent C. Dodds, 2018 | Integration — “Mostly integration”, with static checks as the base | A few | A front end, where the meaningful unit is a component with its children |
| Honeycomb | Spotify, 2018 | Integration tests through each service’s own API | “even fewer … (ideally none)” | Microservices, where the complexity lives in the interactions |
| Ice-cream cone | The anti-pattern both Fowler and Google name | End-to-end and manual tests | Most of the suite | Never on purpose |
The shapes disagree about the middle and agree about the top. Spotify’s honeycomb wants “even fewer Integrated Tests (ideally none)”, where an integrated test is one “that will pass or fail based on the correctness of another system”. Google’s 2015 post settles for about a tenth. Dodds keeps a few. The disagreement is real and worth leaving visible: a team of independent services can test most interactions through contracts and each service’s APIApplication Programming Interface — contract between programsThe rules one program follows to call another: which requests it may send, in what shape, and what comes back. To the caller it is a contract — everything behind it stays a black box, which is exactly what lets the other side be rewritten without breaking you.Full article →All terms, while a shop that takes money across five systems in one customer’s minute cannot. What none of them says is that the top layer should be large. Fowler states the reason it is small as an assumption rather than a law: “If my high level tests are fast, reliable, and cheap to modify - then lower-level tests aren’t needed.” They rarely are.
What a red journey costs — the arithmetic of flakiness
The runtime is the obvious cost and the least important one. The real expense is the distance between a failure and its cause. When a unit test fails you are looking at one function. When journey 9 fails you are looking at a browser, a front end, a warehouse webhookan HTTP call saying something happenedAn HTTP request one system sends to a URL you registered, to tell you that something happened — a payment succeeded, an order shipped — so you do not have to keep asking. Delivery is usually at least once and sometimes out of order, so the receiver must cope with the same event arriving twice.Full article →All terms, a refund service, a payment sandbox, an email provider and an environment — and possibly at none of them, because the test may simply have checked the inbox before the email arrived.
Size makes that likelier. Google found that over a week 0.5% of its small tests were flakypasses and fails on the same codeA test that passes and fails on unchanged code. The real damage is not the failed run but what follows: once a suite has a few, people start re-running until green, and the suite stops being evidence of anything.Full article →All terms, 1.6% of its medium tests and 14% of its large ones. A journey is the largest test a team owns. And small rates compound: if each case fails for no reason with probability p, a run of n cases goes red with nothing wrong with probability 1 − (1 − p)ⁿ. The table works it out.
| Journeys in the suite | Each flakes 0.5% of runs | 2% of runs | 5% of runs |
|---|---|---|---|
| 12 | 5.8% | 21.5% | 46.0% |
| 60 | 26.0% | 70.2% | 95.4% |
| 400 | 86.5% | ≈ 100% | ≈ 100% |
Read the table as a budget, not a complaint. A suite of sixty journeys at 2% each is red on seven runs out of ten when nothing is wrong. Four hundred journeys at the best rate in the table are red almost nine times in ten. That is why “we will just add retries” is the wrong first move, and why ten times the journeys is not ten times the protection — it is a suite that will be ignored. Twelve journeys at 0.5% go red for no reason about once in seventeen runs, which a team can afford to investigate every time.
| Why a journey went red | What it actually means | What removes it |
|---|---|---|
| The system is genuinely broken | The reason the journey exists. | Nothing should — everything below is the tax on keeping this signal. |
| The test checked before the system finished | A timing bug in the test — the largest single cause of flakiness in Luo et al.’s study (Regression testing). | Wait for the condition: the email in the inbox, the order in the warehouse. |
| The data was not what the test assumed | Shared state between journeys or people. | Each journey creates its own customer, order and card, and removes them. |
| An element moved in a redesign | Upkeep, not a defect. | Find elements by role and name or by a test-id, never by CSS class or position. |
| A third party was slow or down | A decision postponed: which dependencies belong inside the test. | Decide it in writing, per dependency — the table in the next-but-one section. |
Choose journeys, not features
The selection mistake almost every team makes is one end-to-end test per feature. Features are how the backlog is organised. They are not how a customer moves through the product, and covering them one by one gives hundreds of slow cases that mostly re-prove logic already proved below. Choose journeys instead: a small number of paths a customer actually completes, each crossing several services, because the crossing is what is being tested.
The money path — journeys 1, 4–6
Find, add, pay, and the order arrives. If exactly one end-to-end test exists, it is journey 1, because it crosses every service the business depends on.
Getting in and staying in — journeys 2, 3, 11
Sign up, sign in, stay signed in after a reload, recover a password. Session and cookie behaviour is invisible to every lower test.
Across a boundary — journeys 7–10
Work one service starts and another finishes, often hours later in real life: a return the warehouse confirms, a refund an email reports.
A hard rule — journey 12
A permission boundary, a regulated disclosure, an age check. Places where being wrong is a legal event rather than a support ticket.
A sizing heuristic, the one in the callout at the top: one journey for each thing the business could not survive losing, plus one for each seam that exists only in the deployed system. For most products that lands between ten and forty. If yours is in the hundreds, the suite is not more thorough than everyone else’s; it is carrying work that belongs two levels down and paying the highest price per case in the codebase to do it. And when a journey finds a bug, follow Fowler’s rule from the Regression testing page: reproduce it at the lowest level that can, so the journey is the second line of defence, not the only one.
Making twelve journeys trustworthy
A trustworthy end-to-end suite does not come from better assertions. It comes from removing every source of variation that is not the behaviour under test, and five of them are worth handling on purpose.
- Wait for a condition, never for a duration. A fixed sleep is too short on a loaded machine and wasted on a fast one; waiting for the element, the email or the warehouse record is both faster and stable.
- Give every journey its own data. It creates the customer, the order and the gift card it needs, and removes them afterwards. A journey that depends on a record someone else made fails on a Tuesday for no reason.
- Find elements the way a person does — by role and visible name — or by a test-idan attribute tests hold on toAn attribute added to markup for the sole purpose of letting tests find an element. It exists so a test does not hold on to a CSS class or a piece of visible text — both of which change for reasons that have nothing to do with behaviour.Full article →All terms, never by a CSS class or a position, both of which change whenever a designer touches the page.
- Control the clock. A journey that depends on today’s date passes in March and fails on the last day of a month; set the date, and then walk the dates that break things on purpose — the 30th day of a return, the 29th of February.
- Capture enough on failure to diagnose without reproducing: a trace, a video, the network log and the browser console. The cost of a red journey is the investigation, and artefacts are what shorten it.
The sixth source is the outside world, and it needs a decision per dependency rather than a default. The test asks one question about each: is this part of the journey I am proving, or something the journey merely touches?
| Dependency | In the shop’s journeys | Why |
|---|---|---|
| Payment provider | Real, in its sandbox | The money path is the point of journeys 1 and 4–6; the sandbox has cards for success, decline and 3-D Secure. |
| Email provider | Real, in test mode, into a test inbox | Journeys 2, 3, 8 and 9 end with an email a customer acts on. |
| Carrier’s label service | Stub, checked by a contract test | The carrier has no sandbox; the journey proves the shop’s side of the return. |
| The assistant’s model | Replayed from a recording | Journey 7 proves the plumbing; the nightly evaluation judges the answers. |
| Analytics, maps, chat for marketing | Blocked at the network boundary | Not part of any journey’s outcome, and the commonest source of slow, random reds. |
Retries deserve a policy rather than a default. Retrying a whole journey hides real intermittent bugs, because a race in the product looks exactly like a flaky test from the outside, and the retry turns a genuine defect into a green tick. The shop’s rule is the one on the Regression testing page: one retry at most, recorded as a signal in its own right, and a journey that needed two retries in a week goes to quarantine. A suite whose green result depends on retries is not green; it is unmeasured.
Three failures where a test stopped one step short
In none of these was the testing skipped. Each time a test ran and passed. It checked a step short of the outcome that mattered, stopped just before the seam where the defect lived, or ran in a place that was not shaped like production.
| Failure | What was tested, and what happened | The step the test stopped short of |
|---|---|---|
| Windows Azure, 29 February 2012 | The leap-day bug itself is told on Data Modeling. Repairing seven half-updated clusters that night, engineers tested the fix on one server: its virtual machines “started successfully and appeared to be healthy”. The package also carried a networking plugin built for the newer agent. It was pushed to every server in those clusters at once, and their virtual machines lost the network. | The outcome a customer needs: can I reach my machine? Microsoft wrote that the test “had not included testing network connectivity to the VMs”; the second attempt, at 3:40 a.m., was tested “this time verifying VM connectivity”. |
| TSB, 22 April 2018 | The migration weekend is told on Release Planning. Production ran in two data centres side by side. On 28 February a testing forum chose to performance-test both together; the bank then accepted a proposal to test one, to keep live services such as cash machines running. After go-live, a customer signed in through one data centre and the next request went to the other, where the session did not exist: “your session has expired”. | The production topology. The FCA’s notice: services “may functionally work end-to-end with one user” and not under load, and had the test run in both data centres, “it is likely that this issue would have been identified”. |
| Boeing Starliner, 20 December 2019 | The uncrewed test flight missed its orbit insertion burn: the capsule’s mission clock was wrong, so the software believed the burn had happened hours earlier, and the flight never reached the space station. Boeing had tested the software in chunks. The joint simulation with the rocket’s maker stopped at separation; the burn came about half an hour after liftoff. A second error, a wrong thruster map for the service module, passed its qualification test on an emulator that did not have the correct map either. | The next seam. Boeing’s programme manager: “If we had run that integrated test for a number of minutes longer, it would have uncovered the issue.” A stand-in at a seam proves only what the stand-in was built to believe. |
Where it degrades
The honest limit is that twelve journeys prove twelve paths worked once, in one environment, with one set of data. Production-like is not production: the real traffic, the real third parties and the real calendar arrive only after the deploy. That is where the smoke gate and synthetic monitoring take over, running the same journeys against production on a schedule. And an end-to-end suite cannot find a defect on a path nobody walked; it can only keep the walked paths from breaking unnoticed.
- An ice-cream cone: most of the testing done through the browser, few tests below, so every failure is an hour of investigation.
- One test per feature, so four hundred cases mostly re-prove logic already proved in milliseconds.
- A browser test against a mocked back end, reported as end to end.
- Journeys that end on the confirmation screen instead of at the outcome — the parcel, the refund, the email.
- One long case walking fifteen screens, so a failure says only that something in fifteen screens is broken.
- Journeys that depend on running in order, so one failure cascades into six and the report describes nothing.
- A suite run only at night, so a regression is blamed on a day of merges rather than on one commit.
- An environment kept by hand that nobody can rebuild, which fails for its own reasons more often than for the code’s.
- Retries on everything, and sleeps scattered through the code as the standard fix.
When to use it
Use it when
- For the handful of journeys the business could not survive losing, each crossing several services in the deployed system.
- For behaviour that exists only once the real pieces are joined — sessions, redirects, configuration, the built front end.
- Against an environment rebuilt from the artefact that ships, with production’s topology, so a pass says something about production.
- Spread over parallel workers, so the suite is fast enough for every merge rather than once a night.
Avoid it when
- For validation rules, error copy, sorting and arithmetic — anything a component or API test proves in milliseconds.
- As the main body of the test suite, where the cost per case is highest and the cause furthest from the failure.
- Against a shared, long-lived environment with hand-made data, where every result depends on what a colleague did an hour ago.
- With blanket retries to keep the pipeline green, which turns genuine intermittent defects into passing runs.
Sources and method
What this page stands on
- 12 sources
- 3 documented failures
- Checked October 18, 2026
The failures this page learns from
the failures in “Three failures where a test stopped one step short”- PostmortemBill Laing — Summary of Windows Azure Service Disruption on Feb 29th, 2012 (opens in a new tab)Microsoft Azure · Mar 9, 2012
- Regulator reportFCA — Final Notice: TSB Bank plc (opens in a new tab)Financial Conduct Authority · Dec 20, 2022
- ArticleStephen Clark — Boeing says thorough testing would have caught Starliner software problems (opens in a new tab)Spaceflight Now · Feb 28, 2020
The shapes of a test suite
the table and the disagreement in “Pyramid, trophy, honeycomb”- ArticleMartin Fowler — TestPyramid (opens in a new tab)martinfowler.com · May 1, 2012
- ArticleHam Vocke — The Practical Test Pyramid (opens in a new tab)martinfowler.com · Feb 26, 2018
- ArticleMike Wacker — Just Say No to More End-to-End Tests (opens in a new tab)Google Testing Blog · Apr 22, 2015
- ArticleKent C. Dodds — The Testing Trophy and Testing Classifications (opens in a new tab)kentcdodds.com · Jun 3, 2021
- ArticleAndré Schaffer, Rickard Dybeck — Testing of Microservices (opens in a new tab)Spotify Engineering · Jan 2018
Practices and where the terms come from
the definitions, the guiding principle and the size numbers in “What a red journey costs”- StandardISTQB Glossary — end-to-end testing (opens in a new tab)ISTQB
- StandardISTQB Glossary — test pyramid (opens in a new tab)ISTQB
- DocumentationGuiding Principles (opens in a new tab)Testing Library
- ArticleJeff Listfield — Where do our flaky tests come from? (opens in a new tab)Google Testing Blog · Apr 17, 2017
Researched with Claude. Finding and cross-checking the primary sources was done with Claude (Anthropic). Selection, writing and fact-checking: the Anatomy of IT Product editors.
Found this useful?
Share it with someone who is working on the same problem.