# Testing software: unit, integration, end-to-end and user acceptance tests

Source: https://sarang.pro/software-testing-unit-integration-e2e-uat/
Author: Sarang | Published: 25 October 2026

Every software change carries a risk of breaking something that used to work. Testing is how a team finds out before customers do. When a developer says "the tests are green" or a quote includes a line for "QA", it helps to know what kinds of testing exist, what each one catches and what a sensible mix looks like.

This guide explains the four types you will hear about most (unit, integration, end-to-end and user acceptance testing) and how they fit together. It also covers what you, as the founder or product owner, should do in the process.

## Why automated tests matter
Testing by hand is slow and easy to skip under deadline pressure. Automated tests are code that checks other code, and they can run every time someone makes a change. The UK Government's Service Manual guidance on [testing your service regularly](https://www.gov.uk/service-manual/technology/quality-assurance-testing-your-service-regularly) says teams "should aim to automate as much of your testing as possible" and run tests continuously, so you "can also spot defects before they develop into bigger problems". A key goal is that changing the code "will not break existing functionality", which testers call avoiding regressions.

Automation doesn't replace people. The same guidance lists exploratory testing, accessibility testing, performance testing and security testing alongside functional checks, and says to "test the usability of your service as well as the technical parts".

## The four main types of test

### Unit tests
A unit test checks one small piece of code, such as a function that calculates delivery cost, on its own. Ham Vocke's article [The Practical Test Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html), published on Martin Fowler's site, explains that other parts of the system are often replaced with stand-ins so the test focuses on one thing. Unit tests run in milliseconds, so a project can have thousands and run them on every change.

### Integration tests
Integration tests check that your code works with things outside it: the database, the file system, or another service. In Vocke's words, "they test the integration of your application with all the parts that live outside of your application". A typical example is checking that saving an order really writes the right record to the database.

### End-to-end tests
End-to-end tests drive the whole system the way a user would, often by automating a browser to click through a journey: search, add to basket, check out. They give the most confidence that the whole thing works. They are also the slowest and most fragile. Martin Fowler's note on the [test pyramid](https://martinfowler.com/bliki/TestPyramid.html) describes tests that run end to end through the user interface as "brittle, expensive to write, and time consuming to run".

### User acceptance tests
User acceptance testing (UAT) checks that the software meets the business need, judged by the people who will use or own it. Wikipedia's entry on [acceptance testing](https://en.wikipedia.org/wiki/Acceptance_testing) quotes the ISTQB definition: "Formal testing with respect to user needs, requirements, and business processes", used to decide whether to accept the system. It notes that UAT should be done by the intended users or subject-matter experts, with test cases based on acceptance criteria, and that in agile work "a user story is not considered complete until it has passed its acceptance tests".

## The test pyramid
The test pyramid is a picture of a healthy balance. Vocke credits Mike Cohn with the idea, from his book *Succeeding with Agile*.

LayerHow manySpeedWhat it catchesEnd-to-endFew, covering key journeysSlowBroken user journeys across the whole systemIntegrationSomeMediumProblems connecting to databases and other servicesUnitManyFastLogic errors in individual pieces of codeFowler's "essential point is that you should have many more low-level" unit tests than tests that go through the interface. Vocke warns against the opposite shape, the "ice-cream cone", where a team relies mostly on slow end-to-end and manual tests. He suggests limiting end-to-end tests to the few journeys that matter most, and using the layers below for everything else.

User acceptance testing sits alongside the pyramid rather than inside it. It answers a different question: not "does the code work?" but "is this what we needed?"

## A worked example
An example (illustration only). An online bakery adds a feature that gives free delivery on orders over a set amount, except for same-day delivery.

- Unit tests check the delivery calculation: an order just below the threshold pays delivery, one just above doesn't, and same-day orders always pay.
- An integration test checks that the delivery charge is saved correctly with the order in the database and passed to the payment provider.
- One end-to-end test runs a full checkout above the threshold in a browser and confirms the total shown matches what is charged.
- The founder does acceptance testing on the staging site, working through the acceptance criteria from the user story, including on her phone. She notices the basket doesn't tell customers how much more they need to spend for free delivery, which wasn't in the criteria. It becomes a new story.
Two weeks later, a developer changes the same-day delivery logic for another reason. A unit test fails immediately, and the bug never reaches customers.

## What founders should do
- Ask what tests exist and when they run. Good answers mention automated tests running on every change, before anything is released.
- Write acceptance criteria for every story, so there is something concrete to test against.
- Do acceptance testing yourself, or name the person who will. Use a staging environment, not the live site.
- Budget for testing. A quote with no time for tests is a quote for problems later.
- Ask for a test to be added for every bug fixed. Fowler recommends reproducing a bug with a unit test before fixing it, so "the unit test ensures the bug stays dead".
- Include security checks. OWASP's guidance on [broken access control](https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/) recommends that developers and QA staff include access control rules in their unit and integration tests.

## Common mistakes
- Relying on manual clicking before each release. It is slow, inconsistent and gets skipped when time is short.
- Too many end-to-end tests. Suites become slow and flaky, and teams start ignoring failures.
- Treating passing tests as proof the product is right. Tests check what someone thought to check. Acceptance and exploratory testing find what nobody thought of.
- Skipping UAT because "the developers tested it". Developers check that code works as written; you check that it does what the business needs.
- Not fixing failing tests. A test suite that is often red stops being trusted.

## When to invest more or less
Invest heavily in automated tests for code that handles money, personal data, permissions or core business rules, and for products that change often. A short-lived prototype built to test demand might reasonably have few automated tests, as long as everyone agrees it will be rebuilt properly if it succeeds. Most products sit in between: a solid base of unit tests, integration tests for each external connection, a handful of end-to-end checks on the journeys that make money, and a person from the business who signs off each feature.