Testing is not optional. In professional software engineering, if it's not tested, it's broken.
- Regression Prevention: When you add features later, tests ensure you didn't break existing ones.
- Documentation: Tests show exactly how the code is expected to behave.
- Confidence: You can refactor code without fear.
We implemented a simple unit test for the Scanner in tests/test_scanner.c.
void test_scenario() {
// 1. Arrange (Setup)
const char *input = "ABC";
Scanner scanner;
scanner_init(&scanner, input);
// 2. Act (Do something)
char result = scanner_next(&scanner);
// 3. Assert (Check result)
assert(result == 'A');
}We use <assert.h>. If assert(condition) fails, the program crashes immediately with an error message. This is perfect for development testing.
We added a test target to the Makefile.
make testThis compiles the test program, links it against our library, and runs it.
- Unit Testing: Testing small units (Scanner) in isolation.
- Assertions: Using
assertto enforce correctness. - Automation: Making tests run with a single command.