Levels of Testing
Validation doesn't happen all at once against the whole finished app. It happens at increasing scales, called levels of testing — starting from the smallest possible unit of code and widening out to the entire product being judged by a real user. Each level catches a different category of problem, and skipping one doesn't get compensated for by doing more of another.
1. Unit Testing
| Checks | A single function, method, or smallest testable piece of code, in isolation from the rest of the app |
| Who performs it | Developers, usually with automated unit test frameworks, as they write the code |
| RecipeBox example | Does calculateTotalTime() correctly sum up prep time plus the time for each cooking step? Feed it a known list of steps and a known prepMinutes value, and assert the returned total matches the hand-calculated answer. |
2. Integration Testing
| Checks | Whether two or more units/modules work correctly together — the handoff points between pieces that each passed their own unit tests individually |
| Who performs it | Developers and/or testers, once the individual pieces exist |
| RecipeBox example | Does tapping "Save" on the Add Recipe screen correctly write the new recipe to the local database and cause the Recipe List screen to immediately show it? This exercises the connection between the save logic, the database layer, and the list screen — three units that each might pass their own unit tests but still fail when wired together. |
3. System Testing
| Checks | The complete, fully integrated application, end to end, against its overall requirements — as close to "the whole real app" as testing gets before release |
| Who performs it | Dedicated QA/testers, on a build that's as close to production as possible |
| RecipeBox example | A full end-to-end pass through the app: log in, browse the Recipe List, search for a recipe, add a new one with a photo, edit it, delete it — confirming every screen and every flow works correctly together, not just the one feature under active development. |
4. Acceptance Testing
| Checks | Whether the finished software actually meets the real-world needs of its intended users/customers — the final "is this good enough to ship" gate |
| Who performs it | End users, clients, or product stakeholders (this is the basis of User Acceptance Testing, covered later in this track) |
| RecipeBox example | A small group of real home cooks tries RecipeBox for a week and confirms it genuinely helps them save and find recipes the way they expected — not just that every button technically works, but that the app is actually useful and pleasant to use. |
Note: These four levels sit on top of each other, and each catches problems the level below it structurally cannot. Unit tests can't catch a broken handoff between modules; integration tests can't catch that the app forgot a feature the user actually needed; system testing can't tell you whether users like using the product.
Putting it all together
Unit → calculateTotalTime() returns the right number
↓
Integration → Save button writes to DB AND updates the Recipe List
↓
System → The whole RecipeBox app works end-to-end
↓
Acceptance → Real users agree RecipeBox meets their needs
Next up: Another way to slice testing is by how much of the internal code the tester can see — Black, White & Grey Box Testing.