Technology - Non SAP

Unit vs Integration vs E2E Testing — The Real Difference

I have sat in enough sprint reviews where someone proudly reports ‘95% test coverage’ right before a production incident wipes out that confidence. The coverage number was never the problem. Nobody had checked what kind of tests made up that number.

Unit, integration and end-to-end testing get used interchangeably in stand-ups. A developer says ‘I tested it’ and the room assumes everyone means the same thing. They rarely do — and the gap between what was tested and what should have been tested is exactly where production bugs come from.

This post breaks down what each test type actually checks, why the ratio between them matters more than the total count, and — because I still think in SAP project terms most days — how this maps onto the SIT and UAT phases you have sat through on every implementation.

🔗 Related Reading

This post builds on CI/CD — From Code Commit to Live in Production and Git — The Mental Model. The tests covered here are exactly what should be running inside the pipeline described there, on every commit.

What each type of test actually checks

Before the detail, the one-sentence version of each. Get this straight and the rest of the post is just depth.

Test typeWhat it checksTypical speedWho usually writes it
UnitOne function or method, completely isolated from its dependenciesMilliseconds — thousands can run in a single buildThe developer, usually in the same sitting as the code
IntegrationTwo or more components working together — a service and a database, an API and a clientSeconds — run on every buildDeveloper or QA engineer
End-to-End (E2E)A full user journey through the whole system, front to back, as a real user would experience itMinutes — usually run nightly or before releaseQA engineer, often automated with tools like Playwright or Cypress

📌 Key Takeaway

The type of test is defined by scope, not by the tool. The exact same testing framework can produce a unit test or an integration test — what matters is what the test actually touches.

Unit testing — fast, isolated, cheap

A unit test checks one function in complete isolation. Every dependency — the database, the API, the file system — gets replaced with a mock or a stub that returns exactly what you tell it to return.

Take a discount calculation function. A unit test does not need a real order sitting in a real database. It calls the function with a fake order object and checks the output. If the function is wrong, the test fails in milliseconds, on the exact line.

This is why unit tests are the foundation of any suite. They are cheap to write, cheap to run, and when one fails, you know almost exactly where the bug is — no digging through logs across three services.

💡 Practical Tip

If a so-called unit test needs a live database connection, a real network call, or a file on disk to pass, it is not a unit test anymore. It is an integration test that forgot its name.

What a unit test cannot tell you is whether the pieces work together. Every individual function can pass its unit tests and the system can still be broken the moment two of them talk to each other. That is exactly what the next layer is for.

Scope diagram on white background showing what falls inside the test boundary for unit, integration and end-to-end tests, with mocked versus real dependencies marked

Integration testing — where modules actually meet

Integration testing checks that two or more components work correctly together — a service writing to a real (or realistic) database, an API client calling a real endpoint, a message being published and actually consumed.

This is the layer that catches bugs unit tests are structurally unable to catch. A database column type does not match what the service expects. An API returns a field the client never accounted for. Every one of these lives at the seam between two pieces, not inside a single function.

Mike Cohn called this the forgotten layer of testing when he first described the test automation pyramid, in his 2009 book Succeeding with Agile. Teams write plenty of unit tests, skip straight to end-to-end tests, and leave the middle almost empty. That is still the single most common testing mistake I see on projects today.

⚠️ Warning

Skipping integration tests does not make your system more integrated — it just moves the discovery of integration bugs from your pipeline to your users.

End-to-end testing — the whole system, the user’s eyes

An E2E test drives the application the way a real user would — open the browser, click the button, fill the form, submit the order, check the confirmation screen. Tools like Playwright, Cypress and Selenium automate exactly this.

E2E tests give you the highest confidence of any layer, because they are the closest thing to reality. They are also the slowest, the most expensive to maintain, and the most likely to fail for reasons that have nothing to do with your code — a slow network, a flaky third-party widget, a timing issue in the browser.

This is where the pyramid gets inverted in practice. Teams that get burned by a bug slipping through respond by adding more E2E tests, because those feel closest to ‘real’ testing. The suite gets slower, flakier, and eventually nobody trusts it enough to block a release on a failure. That is the opposite of what testing is supposed to buy you.

✅ Best Practice

Reserve E2E tests for the handful of journeys that would genuinely hurt the business if they broke — checkout, login, payment. Let unit and integration tests catch everything else.

Comparison diagram on white background showing an inverted testing pyramid with too many E2E tests versus a balanced pyramid with a wide unit test base

The testing pyramid — getting the ratio right

Mike Cohn’s original pyramid puts a large base of unit tests, a smaller layer of integration (‘service’) tests in the middle, and a thin cap of UI/E2E tests at the top. The shape is the point — spend most of your effort where tests are fast and cheap, and least where they are slow and expensive.

A Google engineer, Mike Wacker, put a number on this in a widely cited 2015 testing blog post: a 70/20/10 split as a reasonable starting point — 70% unit, 20% integration, 10% end-to-end. It is a heuristic, not a law, but it is a far better starting point than no ratio at all.

In 2018, Kent C. Dodds proposed an alternative he called the testing trophy, building on an earlier observation from Guillermo Rauch: write tests, not too many, mostly integration. Dodds’ version adds a static-analysis layer at the bottom and shrinks the unit layer, arguing that for most modern frontend applications, integration tests give the best return for the effort.

I do not think either model is ‘correct’ on its own. What matters is that you have deliberately decided your ratio, instead of ending up with whatever ratio the last six sprints under deadline pressure happened to produce.

📝 Note

Which shape suits you depends on your architecture. A backend-heavy system with a lot of internal business logic leans pyramid. A thin frontend calling well-tested backend services leans trophy. Neither excuses skipping the middle layer.

How this maps to SAP project testing (SIT, UAT)

If you have worked an SAP implementation, none of this is new — it just has different names. Unit testing on an SAP project usually means a functional consultant or ABAP developer testing one piece of config or one custom program in isolation, in the development system.

System Integration Testing (SIT) is the SAP-world equivalent of the integration layer, scaled up to the whole landscape. SIT verifies that modules, interfaces, IDocs and Fiori apps pass data correctly across a full business process — SD to FI, MM to FI, a sales order flowing end to end. It runs in the QA system after unit testing, and it is the phase most often squeezed when a go-live date gets tight.

User Acceptance Testing (UAT) is the closest SAP equivalent to E2E — business users running predefined scenarios in a near-production environment before formal sign-off. The distinction that matters: SIT proves the system works technically. UAT proves the system works for the business.

Dev-world conceptSAP project equivalentWho runs it
Unit testingUnit testing — config, custom program, user exitDeveloper / functional consultant, in the dev system
Integration testingSIT — System Integration TestingTesters / consultants, in the QA system
End-to-end testingUAT — User Acceptance TestingBusiness users, in a near-production environment

⚠️ Warning

SIT and UAT are project phases, run by different people at different points in an implementation. Unit, integration and E2E are test types, run continuously by engineers. They map onto each other, but conflating the two is a common source of confusion when SAP consultants move into general software conversations.

Side-by-side mapping diagram on white background connecting developer test types unit, integration and E2E to their SAP project equivalents unit testing, SIT and UAT

At a glance — the differences

ConceptOne-line summary
Unit testChecks one function in isolation — fast, cheap, pinpoints the exact bug
Integration testChecks that two or more components work together — catches bugs at the seams
End-to-end (E2E) testDrives the full system like a real user — highest confidence, slowest and most brittle
Testing pyramidMike Cohn’s 2009 model — a large base of unit tests, fewer integration tests, a thin cap of E2E
70/20/10 splitGoogle’s 2015 heuristic — 70% unit, 20% integration, 10% end-to-end, as a starting ratio
Testing trophyKent C. Dodds’ 2018 alternative — static analysis plus a bigger emphasis on integration tests
Inverted pyramidThe common failure mode — too many slow E2E tests, too few unit and integration tests
SIT (SAP)System Integration Testing — the SAP-project equivalent of the integration layer
UAT (SAP)User Acceptance Testing — the SAP-project equivalent of E2E, run by business users before go-live

What to take away

The number of tests you have was never the useful metric. The distribution across these three layers is. A hundred E2E tests and no integration tests will tell you your login page works and nothing about the fifteen ways your services can silently disagree with each other.

Every layer exists because the layer below it cannot see far enough. Unit tests cannot see across a seam. Integration tests cannot see the whole user journey. E2E tests cannot tell you where, inside a five-second failure, the actual bug is. You need all three, in the right proportion, or you are paying for coverage you do not actually have.

🔗 Related posts on this site

CI/CD — From Code Commit to Live in Production — where these test types actually run, gated on every commit.

Git — The Mental Model — the foundation every pipeline and every test suite sits on top of.

SAP Activate — The Methodology Behind Every S/4HANA Project — where SIT and UAT sit inside the wider project timeline.

ABAP Fundamentals That Still Matter — for the SAP-side unit testing story in more depth.

Published on rakeshnarayan.com — Articles

URL: https://rakeshnarayan.com/articles/unit-vs-integration-vs-e2e-testing-the-real-difference/