Even if this was true, Test-Driven Development would be useful for realizing an up-front design. Humans make so many mistakes coding, the feedback loop of TDD helps you find those mistakes in the most efficient way I’ve ever seen (but I’ve only seen what I have seen). Certainly Test-First Programming (TFP) more effective than predominant programming practice, Debug Later Programming. TDD is much more than TFP. Let me debunk this fake news.
My First 2 decades of development
For about the first twenty years of my programing career, I pursued big design up-front (BDUF). Teams I led got pretty good with with BDUF. We would collect requirements for months on end. Get customers approval, then hide and do our design work, implement the system and go to the lab. We had specs, diagrams, text, pseudo code, and reviewed it all. It was an improvement over the chaos approach before BDUF. Our cycle time was an impressive 6 to 12 months (ahem). Sometimes we even made the deadline.
I worked mostly in embedded systems. When we finally got hardware, with anticipation we fired up the system somehow expecting it to work. Guess what? The system crashed. Now, late in the development cycle we had to deal with the mistakes, wrong requirements, untried hardware, unconfirmed design ideas and assumptions made to get to this point.
With reality setting in, we were forced to the iterative and incremental process we all know too well, debugging.
A Chage of Course in 1999
Thankfully my path changed in 1999. I attended the first Extreme Programming Immersion in the suburbs of Chicago at Object Mentor, my employer at the time. Kent and the crew described problems with development that I was all too familiar with: Late delivery, no warning of coming problems, defects delivered to customers, deteriorating design, and on top of that the burned out developers suffering through a death-march.
Kents 12 practices of XP seemed to address many of the problems. The techniques did not require a long explanations and a long time to payback. The logic-chain from problem to solution was made of only a few links. The discrete practices supported each other. We could try the ideas pretty easily and find out for ourselves.
I’d say at the time, XP was light on design advice. That was OK, because many of us early learners had already invested a lot in learning design. Robert Martin’s Object Mentor taught design and coined the term SOLID. We knew our way around upfront design.
XP does not prescribe how much design upfront is needed because each system has different needs. A small team needs less formal design than someone on a large multi-team effort. It is easy and ego building to over-engineer and design up-front. It is harder to do just enough design, just in time. We have to take a more humble attitude, we can’t get it all right up-front. Iterate to good design was a major insight by Kent, Ward, Ron, Martin and others that I am grateful to have heard about in 1999.
What experienced Test-Driven Developers simply call TDD today is more of an ecosystem than simply the application of one XP practice with a new name (the old name was TFP). Kent Beck originally used the term metaphor to describe design. It was confusing to me, but included having a system of names and conventions to navigate the design.
Recalling what Ron Jeffries told me back in 1999… design is so important, we do it everyday. When we discover something new about the need, the environment, or the existing system, consider the design impact. Design is not an isolated activity we can do once. Do design every day. Little things matter, and they scale. Ron said “Modularity works!”. TDD encourages modularity. TDD provides subtle pressure on a design to improve cohesion and coupling. These responsibility assignment choices happen at many levels everyday.
For me, design is creating a vision of the overall structure of the system. Design is never done, at least not until you stop supporting the system. Imagine a map of the United States, it’s made up of individual states connected through an interstate highway system. The states are also grouped into regions with different cultures, like Midwest, New England, the Southeast…. The country is sliced north to south into timezones. To navigate this system, diagrams, patterns and naming conventions really help. I want that help.
The TDD ecosystem includes applying design principles and having a vision of how the pieces are connected, how they are grouped and how they interact with each other. How formal does the design need to be? That depends on your situation.
Considering the needs continue to evolve, it is silly to think design happens only in the beginning. Nothing new here. We discovered this while we tried to do BDUF/waterfall in the late 80s. Did we give up on BDUF and waterfall? No. We started a number of little waterfalls. This helped, but we never would have had the insight to get to something like TDD and XP’s iterative and incremental engineering techniques.
Design is hard, learn from those before us
To be good at software development you need a lot of design insight and tools at your disposal. TDD is one of those tools. TDD helps you see your poor design decisions. Added complexity in tests, hard to use interfaces, complex initializations are some of the early warnings.
What are some of the other design principles and concepts the test-driven developer needs to understand and apply:
- Principle of Least Knowledge.
- Separation of Concerns (SoC)
- Design Patterns
- Hexagonal architecture (ports and adaptors)
- Recognizing code smells
- Envisioning a better design
- Refactorings and incremental improvement
- Law of Demeter (LoD)
There is plenty of design in the TDD ecosystem. Design is so important, do it all the time. BTW: you don’t have to learn TDD. Find another fast-feedback way to work. I would love to hear about it.
Here are a couple of other articles, from 2012 ,on the topic of TDD has no design.