2024 Public Training Schedule
December 9 – 12, 2024 – Agile Analysis and Design Patterns
Half-Day Sessions
(c) 2024 To Be Agile
Another important aspect of doing emergent design is doing it safely and that means doing it while code is under test. But not just any tests, we have to write behavioral tests that don’t break when we refactor our code to emerge our designs.
These are precisely the kind of tests that I’ve been talking about when advocating for doing test-first development. Using test-first development allows us to create behavioral tests for the code we write that supports us when we refactor our code.
The advantages are many-fold. Test-first development gives us a suite of regression tests that allows us to continually validate the behaviors of the system that then becomes the basis for continuous integration and a rich level of feedback about the system as it’s being built.
But more than the regression tests that I get from doing test-first development, it helps me organize my thinking and build out a system more efficiently then if I were to do test-after development. It’s pretty well-established in the industry that having automated regression tests is valuable. From what I can see many teams builder regression tests after the code is built and oftentimes by the QA department rather than the developers who wrote the code.
In some ways, this relegates tests to a secondary position and we end up not deriving as much benefit from them. When we write our code before we write our tests, we often end up writing code that’s difficult to test that requires us to go back and change it later to make it testable.
That doesn’t happen when I do test-first development. Test-first development t requires that I always write testable code. When I write the test before I write my code I’m leveraging my test in several ways that help me lock down my method signature and what I expect back. It also sets my expectation for when the implementation of the behavior will be done. And I also end up getting a suite of automated regression tests. How cool is that?
Since the essence of building out a system using test-first development is really coming up with good examples and working through those examples to build out their implementations, it should be no surprise that this process is a core part of doing emergent design. In other words, doing emergent design is all about doing good design by coming up with examples and then implementing them in code. If we start simple and build on behaviors as we go then we are emerging a design.
I have seen teams take this approach and build beautiful systems. I have also seen teams pervert this approach and build big balls of mud. The difference, as far as I can tell, is whether or not they paid attention to the things that their code and that their design was telling them.
Again, focusing on good code quality and observing what your designs need in order to be robust is a critical part of doing emergent design effectively. The unit tests that we write when doing test-first development give us a different and much-needed perspective on our system. This perspective of writing testable code helps us build systems that are more resilient to change.
Test-driven development, or test-first development as I prefer to call it, is a discipline that not only helps us get the right kind of regression tests to support us in refactoring our code, it also helps us design testable behaviors in code. These things are essential components for doing emergent design.
Note: This blog post is based on one of the “Seven Strategies…” sections in my book, Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software.
Previous Post: « Understand Design Patterns
Next Post: Understand Refactoring »