Foreword

Throughout my 30-year career as a computer science and software engineering educator, especially since my brief stint in industry in 2001, few other techniques have shaped and pervaded my teaching (and research) as much as automated unit testing, the general approach that test-driven development (TDD) operationalizes into a specific, yet widely applicable technique. 

I still remember catching on to TDD in a concrete sense, almost as a side effect, after adopting Martin Fowler’s 2003 text, UML Distilled (3rd edition), as a UML reference for my object-oriented development course. There, Martin discusses three key practices that are usually found in successful iterative development processes: automated regression tests, refactoring, and continuous integration. This concise description strongly resonated with me, and I’ve always enjoyed convincing my students to have more fun by writing additional code to test the rest of their code and receiving instant feedback in the form of colorful test results.

My other aha moment came almost a decade later, around 2012, when I started to listen to some Software Engineering Radio podcasts about software architecture. I was reading up on some of the references mentioned in the podcasts and came across a brief subsection entitled “Serendipitous Architecture” in “Uncle Bob” Robert C. Martin’s book Agile Software Development: Principles, Patterns, and Practices, which discussed how focusing on making one’s code testable almost automatically leads to good, maintainable architecture.

Taken together, these two points highlight the way automated testing ties together process and architecture, as well as functional and nonfunctional requirements: by giving us more confidence in the extent to which our code satisfies the functional requirements, testability arguably becomes the most important nonfunctional requirement.

This summer, almost another decade later, Saleem Siddiqui contacted me regarding his book. Incidentally, next year will be the 25th anniversary of Saleem having taken three graduate-level courses with me! It has been highly rewarding to see him become a successful technology professional—a ThoughtWorker like Martin Fowler—and author. I felt honored that he asked me to write this foreword for his book and was eager to learn more about his perspective on TDD.

What excites me most about Saleem’s book is that it engages the reader in the TDD process in a hands-on yet methodical way, using a highly familiar running example from everyday life. The red-green-refactor cycle sets the tone for the process regardless of programming language. The successive features from the financial currency domain are concrete and easy to relate to but lead the reader through progressively more complex challenges, thereby building confidence, exposing nuanced tradeoffs, and awakening curiosity to explore further. The final code review along the three dimensions of profile, purpose, and process integrates the insights gathered along the way.

By using three highly visible languages with rather complementary designs—of which JavaScript and Python already occupy top positions in the market and Go is quickly on the rise—Saleem makes a strong case for the broad applicability of the TDD approach. In addition, he provides the reader with additional touchpoints and awareness of the relationship between language design and the “three Ps” just mentioned.

My great hope is for Saleem’s book to have a multiplier effect by resonating with new generations of software developers drawn to impactful languages, such as Go, JavaScript, and Python, and pulling them onto the virtuous path of test-driven development. To borrow the words of the great jazz saxophonist Cannonball Adderley when describing hipness to his live audience in New York, it’s not a state of mind, it’s a fact of life.

Get Learning Test-Driven Development now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.