Lecture 7: Our code implements a method for solving problems we
expect to encounter in the future; but why should we trust those
solutions? We establish the reliability of the code by testing
it. To respect the interfaces of the code, we test the substance
of the answers, not the procedure used to obtain them, even
though it is the reliability of the procedure we ultimate care
about. We test both for the actual answer in particular cases
and by cross-checking different uses of the same code which
should lead to the same answer. Because we do not allow our
tests to give us any false alarms, their power to detect errors
is limited, and must be focused at particular kinds of errors.
We make a virtue of necessity by using a diverse battery of
tests, and shaping the tests so that they tell us where errors
arise. The testing-programming cycle alternates between writing
code and testing its correctness, adding new tests as new errors
are discovered. The logical extreme of this is test-driven
development, where tests