Guided by tests
Updated: Jun 17
In Test Driven Development we write one test at the time. Why is that? Why not just write all of them, and then write the code? One of the main reasons is about the mutual interaction between tests and its code. To be strict, we do not have to start with any complete test at all. The important thing is to have a test that guides the next step we plan to take. A part of writing code is exploring how it will interact with the rest of the world, and the tests are our playground for that. If the code is collaborating well with its tests it will also play nicely with its friends in the codebase.
It is important to start with a failing test, also a simple one. Knowing that feedback is always available, and easy to reach for, will enable us to correct our work constantly. TDD could also have been named Feedback Driven Development. It is not the final test that is its strongest feature. If the function is simple enough to write a correct test for at once, then it is ok. But the 'red-green-refactor' cycle of TDD is also intended to modify the tests. A first failing test ('red') can be to assert that true is false, just to make sure the test can be run. A first passing test ('green') can be that the function under test exists at all. Then the tests will evolve together with the code, always ready to verify the next small step of implementation.
When the feedback is constant, supporting the iterations and not only there to show the end goal, we can truly be guided by our tests. They will be a railing to hold on to, also when we need to take steps that are smaller than one final test.
So make sure to have the system for feedback in place first, and design it to fit only the next step you plan to take. That way you will not lose your footing.
ps. Do not forget to refactor your tests.
ps2. If we write tests as a part of finding an earlier mistake, aka bug, the step-by-step test writing can also be a way to figure out how the code is actually working. Then we can slowly figure out how to test it. Otherwise we might get put down by the expectance to produce a perfect test to reproduce the bug from start. And if bugs hide in that code it might also be code that is hard to test.