How can you ensure and insure that computer programs actually do what they are intended to do? You can’t if you do not test them (on every level, in every context and in every possible situation). Software writing is difficult and will remain to be difficult. There was so much academic talk about verification of programs, using mathematical and logical methods to prove that a program is correct. Big names thought about it: Dijkstra, Hoare, Lamport, and many others. What is the result? Of course nobody would admit that he has been wrong, but in the end, experimental testing was the best possibility to prove the correctness of programs, and automated unit tests have found their way into mainstream programming. Simple code chunks which test code – in a sense code that verifies itself. Good frameworks such as Ruby on Rails support them from the bottom up.
So why are tests important ?
- Unit Tests are a kind of insurance: as long as the conditions are fulfilled, you have a guarantee that nothing bad will happen. Tests are like an insurance that the code still works as intended despite changes, at least in all test cases and in the parts of the application covered by the tests. They guarantee that a change don’t break the code of others, which is especially important in larger teams.
- Tests are also like a real proof that the code works as expected. They are better than any mathematical proof, which may contain errors. Unit tests do not use purely deductive reasoning, and they are not a mathematical proof that the code is correct. They are a real-life verification that the code works for the tested cases: a verification of the application behavior by execution of the real code under real conditions.
- They are a kind of self-verification and self-inspection. Code is used to prove that code works. If for instance continuous integration is used, the code detects itself if it is not working anymore.
- Tests are very useful for refactoring code, esp. if the code was written by somebody else and if the refactoring concerns basic elements which may affect many parts of the system
- Tests are compact examples how to use the code and show hidden dependencies. If you forgot how your own code works or if you must use the code of someone else, you can look at the tests and figure out easily how to use the code in the right way.
- Tests help you write cleaner code. Writing of tests forces the developer to look again over the written code. During these repeated examinations, it is hard to overlook code that “smells”. Obviously simple code which does not repeat itself needs less tests than complex code.
P.S. Even in strongly-typed programming languages the restrictions are verified by the compiler, i.e. by the code itself. Therefore the best method to verify that a code is correct is not a mathematical proof, but rather code that verifies itself.