Growing Object-Oriented Software, Guided by Tests

How a rigorous testing regiment leads to a drama-free software development process

Posted by Grace on December 17, 2021

Header image source: Portal

Growing Object-Oriented Software, Guided by Tests By Steve Freeman and Nat Pryce

This book is an in-depth look at how to use a walking skeleton, TDD and other techniques to grow software that is easy to maintain.

A walking skeleton is the most minimal possible slice of an application that implements the basic functionality and tech stack and can be used to build, test, and deploy end-to-end. For example, a minimal web app that grabs fields from the actual database and is hosted would be a good walking skeleton for a much more complex website. Once this is implemented, the developers can start using TDD with the assurance that whatever their next step is, they will know if it breaks the build now rather than a week before launch day.

As for how to practice TDD, the book goes over this classic TDD cycle -

  1. Write a failing acceptance test:
  2. Write a failing unit test
  3. Make the tests pass
  4. Refactor
  5. (repeat steps 2-4 until acceptance is done)

The acceptance test should cover the entirety of the functionality you are trying to build.

One of the major benefits of TDD is frontloading the uncertainty of test development. The authors ay that if you follow the advice in this book, you shouldn’t have an 11th-hour catastrophe that annoys your clients (or worse). By starting with a “walking skeleton” and then implementing TDD thereon out, developers ensure that their codebase is functional from the get-go and stays that way. This is in contrast to the much riskier workflow of developers working on separate pieces for months and then trying to hook them all together at the last minute.

As for other techniques to help grow easily-maintainable software, the book also recommends that you make sure the error messages are clear. It’s not enough for your test to fail- do you understand why is it failing? Descriptive errors messages are recommended.

Lastly, the book has some helpful philosophical advice on how to handle objects. Always prefer handling data as objects rather than values, because then more can be added to the objects. As the codebase gets more complex, consider breaking out, budding off, or bundling up as needed. If an object is too complex, you can break it off, which means turning it into smaller objects. Budding off is when you make a new class immediately for a new value. Bundling up is where you add some values together into one type with fixed public fields. All these techniques add up to a more object-oriented whole.

Overall, this book was a helpful perspective on how tests can lead to a calmer development process.