Testing at Scale
Testing a single function is one thing; gaining confidence in a whole program is another. As programs grow, testing organizes into levels.
A unit test checks one small piece, a single function or module, in isolation, with dependencies controlled. It is fast and pinpoints failures. An integration test checks that several units work correctly together, verifying that module interfaces fit. A module can pass unit tests yet fail integration because of shared interface disagreements. System (end-to-end) tests exercise the whole program as a user would.
| Level | Scope | What it verifies |
|---|---|---|
| Unit | One function/module | Isolated logic |
| Integration | Multiple modules | Shared interfaces |
| System | Entire program | User-facing behavior |
Coverage & Safety
Test coverage measures how much code the tests exercise, such as the fraction of lines or branches that run during testing. It acts as a necessary base, but it is not sufficient for correctness.
Two enabling practices keep codebases healthy:
- Automated tests: re-run cheaply after every code change.
- Regression safety net: catches when a change breaks previously working behavior.
Common pitfall: treating high code coverage as proof of correctness. Coverage only measures which code ran, not whether results were checked or edge cases exercised. A suite can hit 100% coverage while asserting nothing meaningful.