beginner18 min

Test Levels: Unit, Integration, System, Acceptance

The four traditional test levels, what each one actually catches, and why relying on only one of them leaves real gaps.

What you'll learn

  • Name the four traditional test levels and what scope each one covers
  • Classify a given test scenario by the level it belongs to
  • Explain why a defect can pass unit tests but fail at integration or system level

Prerequisites

Explanation

Two functions can each work perfectly alone and still break the moment they're connected. A payment function correctly calculates a total. A checkout function correctly calls "whatever calculates the total." Plugged together, one expects cents and the other passes dollars — both individually correct, both wrong together. This is exactly why testing happens at more than one level, each with a different scope and a different kind of defect it's positioned to catch.

Unit testing exercises the smallest testable piece of code in isolation — a single function or method — usually by the developer who wrote it, often with dependencies replaced by simple stand-ins. It answers: "does this one piece do what it claims, for the inputs I can enumerate?" It's fast and cheap to run, which is exactly why it's the wrong place to catch a problem that only exists between two pieces.

Integration testing exercises two or more units together, deliberately targeting the seams: does the payment function receive the total in the unit the checkout function actually sends it in? Integration defects are often the most surprising, because each side individually looks correct — the bug lives in the disagreement between them, not inside either piece.

System testing exercises the complete, integrated application against its end-to-end requirements, usually in an environment resembling production. It's the first level where a full user journey — browse, add to cart, pay, receive confirmation — gets exercised as a whole, and where cross-cutting concerns like performance under realistic load first show up meaningfully.

Acceptance testing asks a different question entirely: not "does it work" but "is this what the business actually needed?" It's typically performed by or with stakeholders, checking the system against real-world usage and business requirements before a release decision. A system can pass every unit, integration, and system test and still fail acceptance testing, if it was built precisely to the wrong specification.

The levels are not a strict sequence you complete once and never revisit — in an agile team, all four happen continuously, often for the same feature within the same day. What matters is understanding that each level has a scope, and defects that live outside that scope will simply not be caught there, no matter how thoroughly you test within it.

Example

Each function passes in isolation (unit level) — the mismatch only appears once they're called together (integration level).

// Unit level: each function is correct on its own.
function calculateTotalCents(items) {
  return items.reduce((sum, item) => sum + item.priceCents, 0);
}
function chargeCard(amountDollars) {
  return `Charging $${amountDollars.toFixed(2)}`;
}

// Integration level: wiring them together reveals the real bug.
const items = [{ priceCents: 500 }, { priceCents: 250 }];
const total = calculateTotalCents(items); // 750 (cents)
console.log(chargeCard(total));           // "Charging $750.00" -- should be $7.50!

Try it yourself

Fix the integration bug by converting cents to dollars before calling chargeCard, then re-run.

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Guided exercise

Guided exercise

Classify each scenario by test level using the strings 'unit', 'integration', 'system', or 'acceptance': scenarioA = testing a single validateEmail() function with 10 sample emails. scenarioB = a product manager checks the finished app against the original business goals before sign-off.

Checks: correctly classifies scenario A as unit · correctly classifies scenario B as acceptance

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Independent exercise

Independent exercise

Classify two more scenarios the same way: scenarioC = verifying the checkout module correctly calls the shipping module with the right address format. scenarioD = running the full purchase flow (browse, cart, pay, confirmation email) in a staging environment.

Checks: correctly classifies scenario C as integration · correctly classifies scenario D as system

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Common mistakes

  • Assuming a feature with 100% unit test coverage has no risk left — coverage only measures the unit level's scope.
  • Skipping integration testing because "each piece already has unit tests," which is exactly the gap integration testing exists to close.
  • Confusing system testing (does the whole app work) with acceptance testing (is the whole app what was actually needed) — a system can pass one and fail the other.

Knowledge check

Knowledge check

1. Two functions each pass their own unit tests, but fail when connected together. What does this demonstrate?
2. Which question is most specific to acceptance testing, as opposed to system testing?
3. In a modern agile team, how do the four test levels typically relate to each other?

Takeaway

Each test level has a distinct scope, and a defect outside that scope will not be caught there — real coverage means using multiple levels deliberately, not relying on one.

Summary

This lesson introduced the four traditional test levels — unit, integration, system, and acceptance — what each catches, and why a defect can survive one level and only surface at another.

References

Your notes

Notes save automatically.