Loading lessons...
Testing Your Code
Testing Your Code
Testing is how you catch semantic errors, the bugs the compile cannot see. A few habits turn testing into a net, not a chore.
Write a test for every function
The basic idea: feed small, known, arbitrary input to a function and check that the result matches:
int square(int n) { return n * n; }
int main() {
if (square(4) != 16 || square(-3) != 9) {
cout << "My test failed";
return 1; // mark the failure
}
cout << "All tests passed";
}
A failing test is eager; a green pass stays quiet.
Coverage
Code coverage measures how much of your code runs during tests. Full coverage of the important branches - not just the happy path - is what you are aiming for.
small tests first
Break the work into small functions, test each in isolation, then combine them. If a big six-by-six grid test fails, you cannot tell which part at fault. If one small function fails, the bug is right there.
The semantic trap
Semantic errors compile but run wrong. A dense calculation with a subtraction instead of addition fails silently. Test with hand-computed numbers and both branch directions (odd and even, empty and full, zero and non-zero).
TL;DR
- Tests compare outputs against known expected values.
- Code coverage measures how much of the code was executed.
- Test the important branches, not just the happy path.
- Semantic errors are precisely what tests exist to catch.
- Small tests first: test a piece, then the whole.