Tests As Requirements for Design
If you ask anyone in the software industry if they do any software design, they will all say they do. When you ask them what artifacts do they create when they do software design they usually come up empty handed. Best case, someone will say that they make some sketches on a whiteboard and that’s their design. Let’s look at why designs are so rare, and what can we do to create valuable designs starting now.
Let’s look at three scenarios when design is deemed unnecessary overhead:
- My system is too simple, I don’t need design
- My system is too complex, I can’t design all of this
- Design is diagrams that are not useful for coding
(1) All systems start out small and grow. Dependable small systems can grow in to stable big ones. Based on years of industry experience, it seems that ignoring design in the small is a recipe for a lot of grief later. A design for a small system should also be little effort, but nonetheless valuable effort. So the real question is: why is the design for a small system not valuable?
(2) For a complex system not thinking about design not just at the beginning, but all along is akin to leaving things to happenstance. Yes, the system might work, though I’d rather not leave it to chance. For a complex system creating a design is more like a plan of how this system might come to being. At this level figuring out interactions between part of the system is required, since without knowing this, those parts will not be able to communicate. The design is there to guide the development work, and it is adjusted along the way, as new knowledge emerges.
(3) Considering that design can only be in the form of diagrams is also a common misconception. Design can take the form of many shapes, and diagrams are just one of them. Diagrams are quite useful when you want to look at the bigger picture.
The Way Forward Now
This is what you can do now on your current project: write a test that uses the code you are designing the way it will be used by its consumers (which may be you). You’ll focus on diagrams later. Now focus on creating designs in the form of function signatures for the code that you are developing.
Test-Driven Development (TDD) has been around for decades, however not many see it as a way to create the design of the code, and not only to test an existing design.
Late last year I came across David Farley’s book, Modern Software Engineering, where he states:
“Since we are writing the test first, before we have written any non-test code, that means that we are, at the moment we create the test, also designing the interface to our code. We are defining how external users of our code will interact with it.”
“Since we need the results for the test, we will design the code in a way that makes it easy for us to get at the results that we are interested in. This means that, in TDD, there is a pressure applied to write code that is more testable.”
So we get the benefit of creating a design, and making that design testable at the same time!
David Farley adds:
“One of the reasons that I value TDD so highly, as a practice, is the feedback that it gives me on the quality of my design. If my tests are hard to write, that tells me something important about the quality of my code.”
Let’s not delay writing designs anymore. It is easy to start, so get going. When you open your editor the next time to write some code, start with the test first, not because it’s cool, but because it will make your designs better.