End-to-End Testing vs Integration Testing: What Each Catches (With Examples)

End-to-end testing vs integration testing: what each one sees, the checkout bug only a test of the screen catches, the test pyramid, and how many end-to-end tests you need.

10 min readBy Ait Nohaila, Business Development Representative

End-to-end testing vs integration testing: the one-line difference

Definition

Integration testing checks that two or more parts of an application work together at their seam, through code or an API, while end-to-end testing checks the whole application through its screen, the way a user goes through it.

  • An integration test asks a question of the code: did the cart service return the total the checkout expects?
  • An end-to-end test asks a question of the screen: does the user see the right total where they expect it?
  • Both are needed, and neither can answer the other's question.

The two are confused because both test more than one piece at a time.The difference is where the test stands.An integration test stands at the seam between two parts and watches what crosses it.An end-to-end test stands where the user stands, in front of the screen, and watches the result of everything behind it.

Integration tests check the seam.An end-to-end test checks what is drawn.

E2E vs integration testing side by side

Here is how the two compare on the questions a team asks when it decides what to automate.

QuestionIntegration testingEnd-to-end testing
ScopeTwo or more parts of the application, together: a service and its database, the API and the module that calls it.The whole application as the user meets it, with every part it depends on: the screen, the services behind it, often other systems such as a payment provider.
Entry pointCode or an API: the test calls a function or sends a request and reads the answer.The screen: the test clicks, types and reads what is drawn, the way a person would.
What it findsA part that no longer answers the way the next part expects: a renamed field, a wrong status, a missing record.A journey that no longer gives the user the right result: a wrong total on the screen, a button that does nothing, a page that will not open.
SpeedMilliseconds to seconds per test.Hundreds can run on every commit.Seconds to minutes per journey.A suite of a few dozen runs on every build or every night.
CostCheap to write for the developer who knows the seam, and cheap to run.Costly when it is code: every redesign breaks selectors.Cheap when it is recorded from the screen and kept without code.
Who writes itDevelopers, as they build each seam.Testers, QA engineers and product owners who know what the user expects; developers too.
When it runsOn every commit, in the build, before anything is merged.On every build or pull request for a few critical journeys, every night for the whole suite, on every browser and device before a release.

The bug an integration test cannot see

Take a checkout.The cart service adds the items, the pricing service applies the shipping rate, and the checkout page draws the result in three rows: Subtotal, Shipping and Total.One day a developer tidies the checkout template.A row moves.The code behind it is untouched.

Today's change: the checkout template
Integration test
PASS
POST /cart/total
{ "total": 48.90 }
Expected 48.90, got 48.90. The cart service and the pricing service agree.
End-to-end test
FAIL
Subtotal
$45.00
Shipping
$48.90
Total
The Total field is empty, and 48.90 is drawn in the Shipping row.
The same bug, two verdicts.The API returns the right total, so the integration test is green.The screen shows that total in the wrong row, so the end-to-end test is red.Only one of them is looking where the user looks.

The integration test asks the API for the cart's total and compares it with the number it expects.It gets 48.90, exactly right, and passes.Every service did its job, and the seam between them is sound.

The end-to-end test does what a customer does: add two items, open the checkout, and read the total before paying.On the screen, the Total row is empty, and 48.90 now sits beside Shipping.A customer reads that shipping costs 48.90 and nothing is due.That is a bug no one would argue about, and no integration test can see it, because an integration test never looks at the page.

The same pattern hides many of the bugs that reach users.

  • A total computed in dollars and drawn with a euro sign.
  • A Pay button pushed below the fold by a new banner.
  • A confirmation message that appears behind the window.
  • A label too long for its field after a translation.
  • In every case, the data is right and the screen is wrong.

This is the same gap that visual bugs your automated tests miss describes from the other side: a check that asks whether an element exists cannot tell whether a person can see it, read it or click it.

The test pyramid: where each layer earns its place

The test pyramid is the usual picture of how a suite should be sized.Its shape is about cost, not importance: a unit test runs in a millisecond and can be written for every case, an end-to-end test starts the real application and follows one journey, so there are fewer of them.

The test pyramid: how many tests, and what each layer sees

End-to-end tests
The whole application, through its screen
Integration tests
Two or more parts at their seam
Unit tests
One function, alone
A few journeys
Dozens to hundreds
Hundreds to thousands
Many fast tests at the base, a few slow ones at the top.The top layer is small because each test costs more to run, not because it matters less: it is the only layer that sees what the user sees.

Unit tests

A unit test earns its place by catching a wrong calculation the moment it is written, in the function that made it.

Integration tests

An integration test earns its place by catching a seam that broke: a field renamed in one service and still expected by another.

End-to-end tests

An end-to-end test earns its place by catching what only the screen shows: the right number in the wrong field, the button that cannot be clicked, the page that never opens.

System testing sits next to the top of the pyramid, and many teams use the two names for the same thing.The useful distinction: system testing checks the assembled application against its requirements, end-to-end testing follows one user's journey through everything that journey touches.What end-to-end testing is goes through the whole picture.

Integration testing vs end-to-end testing: when to use which

The choice is rarely one or the other.Each layer is cheapest at a different kind of question, and a team that knows which question it is asking puts the test in the right place.

Use an integration test when the question is about a seam.

  • Does the API still answer the shape the module expects?
  • Does the order reach the database with every field?
  • Does the payment provider's refusal come back as the error the code handles?
  • Those are many small cases, best checked fast, on every commit, by the developer who built the seam.

Use an end-to-end test when the question is about the user's result.

  • Can a customer sign in, find a product, pay and see the confirmation with the right order number?
  • Does the report the finance team exports every Monday still open with the right columns?
  • Those are a few whole journeys, checked where the user would check them, on every build.

Use both where money, data or sign-in is involved.

  • The checkout above needs its integration tests, so a wrong total is caught at the seam that produced it, and its end-to-end test, so a right total drawn in the wrong place is caught too.
  • Neither could have replaced the other that day.

Both layers are regression tests: they are run again after every change to prove nothing that worked has broken.What regression testing is explains when to run each and why suites get abandoned when they cost more than they catch.

How many end-to-end tests do you need?

Fewer than you think, and better chosen.The top of the pyramid is not a place to list every screen.It is a place for the journeys that would hurt most if they broke, each followed from its first click to the result the user came for, and each verifying that result.

Most applications are covered by a short list.

  • 1Sign-up and sign-in, including the error when the password is wrong.
  • 2The main task the application exists for: place an order, book a slot, create a client, submit a claim.
  • 3Payment, through to the confirmation and its order number.
  • 4The search or list a user starts from every day.
  • 5The export or report a customer relies on.
  • 6Every journey that broke once and reached users.

Five to fifteen journeys like these, run on every build, catch most of what an integration suite lets through.Each one ends on a check of what the screen shows: the total, the confirmation, the exported file.A test that clicks through a journey and verifies nothing proves little.

What to verify at each step is a choice worth making on purpose: a picture of the element, its words, or what appeared on the screen.Choose what a test verifies walks through it.

Automate the end-to-end layer without code

The end-to-end layer is the one most teams leave thin, because it has been the costliest to keep: coded tests find elements through selectors, and every redesign breaks them.GUI Test Studio takes the code out of that layer.It tests web apps, Windows desktop apps, Android phones and games through their screen, the way a user does.

Record it, or describe it

Click Record and go through the journey in your real application: add the items, open the checkout, read the total.The clicks, the typing and the checks of what appeared become a test, with no code to write.You can also describe the journey in a prompt to your AI assistant, and the test is created for you.Your first test, step by step takes about ten minutes.

The test checks what the screen shows, not the code behind it.

  • A Visual Assert compares the picture of an element, a Text Assert reads its words, and a check of what appeared catches the dialog or message the step opened.
  • The GTS Engine + AI finds each element through the application's accessibility information first, and by sight when the application does not say.

Run it on every build

gtr-cli runs the end-to-end suite on a Windows build machine and answers the way a pipeline expects: a failed journey fails the build, a JUnit file fills the test tab, and every picture of what failed is kept beside the integration results.

The end-to-end journeys on every build
gtr-cli run tests\journeys --countdown 0 --junit results\junit.xml --artifacts results\artifacts

It works in TeamCity, Jenkins, GitHub Actions, GitLab and Azure DevOps: see Run tests in your pipeline.

The Confidence Report says what changed

Every run ends in a Confidence Report.For each check, it says whether the element was found and whether it still looks the way it was recorded, with the expected and found pictures side by side and the difference outlined.For the checkout above, it shows the Total row empty and 48.90 one row up: exactly what a tester would have written in the bug report.

The expected screen on the left, the one the run found on the right: what changed is outlined, in the words a tester would use.

Noise is ignored and regressions are caught.

  • Slight rendering differences that no person would notice are not counted, while a changed word, a missing badge or a number in the wrong row fails the check.
  • When a picture differs, AI Smart Verification can take a second look and say what changed in plain words, in the cloud with your own key or on your own computer with a local AI model, one we provide or your own.

A change is pushed

The checkout template is tidied

The build runs

Integration tests, then gtr-cli

Confidence Report

The total is in the wrong row

Fixed before merge

The user never saw it

Key takeaways

  • 1Integration tests check the seam between parts; an end-to-end test checks what is drawn for the user.
  • 2The same bug can be green and red at once: the API returns the right total, the screen shows it in the wrong field.
  • 3The pyramid's shape is about cost, not importance: many fast tests below, a few whole journeys on top, each catching what the others cannot.
  • 4Use both where money, data or sign-in is involved, and pick the layer by who would write the bug report: a user or a developer.
  • 5Five to fifteen journeys, each verifying its result, cover most of what the integration suite lets through, and they can be recorded without code.

Questions

What is the difference between end-to-end testing and integration testing?

Integration testing checks that two or more parts of an application work together at their seam, usually through code or an API.End-to-end testing checks the whole application through its screen, the way a user goes through it.An integration test can pass while the screen shows the wrong thing.

Is end-to-end testing the same as system testing?

They overlap, and many teams use the words for the same thing.System testing checks the complete, assembled application against its requirements.End-to-end testing follows a user's journey from the first click to the result, through every part the journey touches, other systems included.

Can integration tests replace end-to-end tests?

No.Integration tests prove that parts agree with each other, not that a user gets the right result on the screen.A total can be computed right by every service and still be drawn in the wrong field or hidden behind a banner, and only a test that looks at the screen sees that.

Which should you write first, integration tests or end-to-end tests?

Developers write integration tests as they build each seam, so those usually come first.The first end-to-end tests belong to the journeys that would hurt most if they broke, such as sign-in and checkout, and they can be recorded as soon as those journeys work.

How many end-to-end tests should a project have?

Fewer than you think, and better chosen.Five to fifteen journeys cover what most applications cannot afford to break: sign-up, sign-in, the main task, payment, the export customers rely on.Each one follows a journey to the result the user came for, and verifies that result.

Why are end-to-end tests slower than integration tests?

An end-to-end test starts the real application, drives its screens and waits for each one to respond, so a journey takes seconds to minutes where an integration test takes milliseconds.That is why end-to-end tests cover a few important journeys, and integration tests cover many cases.

What is the test pyramid?

The test pyramid is a way of sizing a test suite: many fast unit tests at the base, fewer integration tests in the middle, and a small number of end-to-end tests at the top.Each layer catches what the layers below cannot, and the top layer is the only one that sees what the user sees.

Who writes end-to-end tests?

Anyone who knows what the user expects can, when the tool needs no code.With GUI Test Studio, a tester or a product owner records a journey by using the application, or describes it in a prompt, and the test runs on every build with gtr-cli.

TeamCity, Jenkins, GitHub, GitLab and Azure DevOps are trademarks of their respective owners.

Ready to record your first test?

Every feature, for 15 days.

Rather see it on the kind of app you test?Book a free 30-minute call with our team.

Book a demo