Dokven

Loading Dokven.
Core skills 8 min read

The four levels of testing

Unit, integration, system, and acceptance testing: what each one checks, who usually does it, and how they build on each other from the smallest piece of code up to a real user signing off.

Think about building a car. You don't bolt everything together, turn the key, and then discover the spark plugs are duds. You test the spark plug on its own, then the engine it sits in, then the whole car on a track, and finally you let a real driver take it for a spin. Software testing works in the same layered way, from the tiniest piece up to the finished product. We call these the levels of testing.

Four levels, building upward

Acceptance testing

does it meet the user's real need?

System testing

does the whole app work end to end?

Integration testing

do the parts work together?

Unit testing

does each small piece work alone?

Read that from the bottom up. Each level assumes the one below it already passed. There's no point checking that the whole app works end to end if the individual pieces are still broken: you'd just be chasing noise.

Unit testing: the smallest piece

A unit is the smallest testable chunk of code, usually a single function or method. Unit testing checks that one piece does its one job correctly, in isolation. Does the calculateTax function return the right number for an order of $80? Developers usually write these as they build, and they run in milliseconds, so a codebase might have thousands of them firing on every change.

Integration testing: do the pieces fit?

Two units can each be flawless and still break the moment they talk to each other: wrong data format, a mismatched assumption, a missing handshake. Integration testing checks the connections between pieces. There are two broad ways to go about it:

  • Big-bang: wait until all the pieces are built, then wire them up and test everything together at once. Simple, but when something breaks it's hard to tell which connection is at fault.
  • Incremental: add and test one piece at a time, so a new failure almost certainly came from the piece you just added. This splits into top-down (start from the top-level pieces and work down, faking the lower ones) and bottom-up (start from the foundational pieces and build upward).
Tip

Incremental integration is usually kinder to your sanity than big-bang. When you add one piece and a test fails, you barely have to investigate: the culprit is almost always the thing you just plugged in.

System testing: the whole thing, end to end

Now the entire application is assembled, and you test it as a complete product against what was promised, exactly the way a user would move through it. Can someone sign up, search for a product, add it to the cart, pay, and get a confirmation email, all in one unbroken flow? This is where QA testers spend much of their time. System testing also covers the non-functional qualities: is it fast enough, secure enough, accessible enough?

Acceptance testing: would the customer sign off?

The final question isn't "does it work?". It's "is this actually what the customer wanted?" Acceptance testing answers that. The most common form is User Acceptance Testing (UAT), where real users or the client try the software against their real needs and decide whether to accept it. Two related flavours you'll hear about:

  • Alpha testing: done in-house, by people inside the company, before the public sees it. A controlled dress rehearsal.
  • Beta testing: released to a limited group of real outside users in the real world, who report what breaks before the full launch.
LevelChecksUsually done by
UnitOne function or method works in isolation.Developers
IntegrationPieces work correctly when connected.Developers / QA
SystemThe whole assembled app works end to end.QA testers
AcceptanceIt meets the real user's needs.Users / client / business
Why the layers matter

Each level catches a different kind of bug, and catching a bug early is dramatically cheaper than catching it late. A broken function caught in a unit test costs minutes; the same flaw caught by a user after launch costs reputation, refunds, and a frantic weekend. The layers aren't bureaucracy: they're a cost-saving net.

Key takeaways
  • Testing happens at four levels, built upward: unit, integration, system, and acceptance.
  • Unit testing checks one small piece in isolation and is usually written by developers.
  • Integration testing checks that pieces work together: big-bang (all at once) or incremental (top-down / bottom-up, one at a time).
  • System testing exercises the whole assembled app end to end, the way a real user would.
  • Acceptance testing (UAT, plus alpha and beta) asks whether the software truly meets the user's needs.
  • Catching a bug early at a lower level is far cheaper than letting it reach a real user.