When I went to university to study computer science with no word were automated tests in any form mentioned. This was ~15 years ago.
My first encounter which tought me that unit tests are important and (depending on the environment) the easiest way of writing tests was when reading the book “Clean Code” [Clean Code] by Robert C. Martin.
That got me in the right direction. During the next few years I’ve heard about writing “tests first” and TDD (Test-Driven Development). But I couldn’t really imagine how one would write a test first, before any production code? How is that supposed to work?
But the topic was so interessting that after a while I read the book “Test-Driven Development” by Kent Beck. He explains in a step-by-step way the discipline of TDD, which helped me a lot. However, that still felt odd and I couldn’t yet adopt the practice. But it didn’t let me loose either. Somehow I was pulled towards it.
But finally I’ve have adopted it. And after practicing it for ~two years I have to say, once I got used to it, it’s one of the best practices that I was able to learn in my life as professional developer.
Because aside from validating the production code TDD has more advantages, which are kind of automatically applied:
- with TDD you will end up having a good test coverage. That in turn makes you detect regression (changes to the code which might have broken something elsewhere).
- you don’t have to be scared for refactorings. Refactorings should always be done to clean up the code and to make things simpler. Having a good test coverage you don’t have to worry too much about doing refactorings.
- it is documentation for the production code, because tests use the production code. Hence other developers just need to look at the tests to find out how something works.
- it enforces a better structure to your production code (at least that is what I have experienced). When tests get too complicated this is usually a sign that the production is too complicated as well. Then you should refactor. Refactor out components and create separate tests for them. Reduce your dependencies, etc. That will lead to less tightly coupled components and code.
Make no mistake, If you do not write your tests first you will end up having a test suite with a lot of holes. When you run it and it is „green“ it doesn’t really tell you a lot. Since you have not really covered everything there is still a lot of potential where something is broken.
Software tests are similar to empirical tests in science. You cannot prove that a software is bug free. The tests you write and the better your coverage is the more you can assume that you don‘t have a lot of bugs and from that you have to judge whether you trust your test suite and release or not. When do you trust your test suite? When you have applied TDD and have a good coverage.