Coupling and cohesion have been discussed for a long time as the right criteria for judging a design. But there seemed to be no objective way to determine if code exhibited those qualities. Could TDD lead to higher cohesion and loose coupling?
With TDD, you get an early warning when your code starts to loose its good design. One sign of a poor design is when functions and modules do to much. They are do too much–they are losing their cohesion. It is easy to spot when the rot has spread and festered, leading to thousand line plus functions. To any on-looker, the design rot is visible. What were the designers thinking when they implemented this thousand line function? I doubt they were thinking this is the perfect place for a thousand line function. Probably not. Where did this frightening monster come from? It grew. It expanded. It swelled, one line at a time.
Reversing the legacy process, of code followed by testing, forces the design to be testable. When parts of the code become untestable, it becomes obvious. For example, let’s say you are tempted to add conditional logic inside a switch/case. This change might get the feature
Writing tests often provides an objective warning of design rot. A good design, a testable design, always seems to have the smaller less complex functions, showing greater cohesion. Testing parts classes and modules in isolation requires loose coupling. TDD helps to accomplish both.