Test-Driven Development (TDD) typically used in agile development approaches, the idea is develop test cases before writing the actual code. Life cycles of TDD is writing the failing unit test, then write some code to make the test pass and refactor it. TDD turns testing into a design activity. We have to do a good design, that is loosely coupled and highly cohesive code, it means knowing the design principles and patterns that are important to keep the code extensible. TDD is only about writing automated tests? No. Test Driven Development is not a testing technique, it’s more about Design. Hence, I can blame it on the name, which includes the word “test” but not the word “design.”
Many agile processes rejecting the design phase, instead favoring of a small architectural sketch. In such a process, the software design emerges as the software grows. Hence TDD assumes that the software design is either incomplete, or at least open to evolutionary changes.
In a traditional test-last of development, the process involves significant effort in specifying the system architecture and design before any significant software development. In TDD, the project identifies some high-level architecture early, but that design doesn’t proceed to a detailed level. Instead, the test-first process of writing unit tests and constructing the units in short, rapid iterations allows the design to emerge and evolve.
Testing is no longer just about finding bugs. Instead, it’s about helping the team to understand the features that the users want. It improves the quality of the system dramatically (especially internal quality – How easy to understand the code, how easy to change the code base, simplicity, size, coupling, and cohesion etc). It helps the system reliability and flexibility to new requirements. Moreover, it encourages developing loosely coupled components, so they can be tested in isolation and integrated together. Test-Driven Development improves design, it makes it more flexible, it makes it more extensible, it makes it easier to maintain.
During the implementation, we think how the class will be used by other classes. Just writing code without any thought to design does not make sense. When I do traditional up-front design, I don’t think of everything, and the original design often differs to the final implementation. On the other hand, writing, a unit test helps a clean and efficient design for the class. I write down UML sketches to help formalize the ideas, but there is no substitute for trying to write the code that actually uses the class.
People who practice TDD also obtain much better code coverage statistics, lower cyclometric complexity. Testable classes are typically more modular, configurable, flexible and more loosely coupled. TDD is a nice fit for techniques such as Dependency Injection and the use of interfaces, which encourage more loosely-coupled and more flexible components. The use of interfaces and abstract classes are results in more flexible components, rather than more rigid applications.