The Life and Times of TDD
There’s been a lot of hullabaloo lately about the state of test driven development (TDD). This was the result of blog posting and conference presentation by David Heinemeier Hansson entitled TDD is dead. Long live testing. TDD is of course alive and well, albeit not as common as its protagonists would like. This is because TDD requires both skill and discipline on the part of practitioners, and as you will soon see TDD is only one of many practices that disciplined agile practitioners follow.
Let’s start by defining a few terms. TDD is an approach that combines test-first development (TFD) and refactoring. With TFD you write a single test and then just enough production code to fulfill that test. Refactoring is a strategy where you improve the quality of something (source code, your database schema, your user interface) by making small changes to it that do not change its semantics-in other words refactoring is a clean-up activity that makes something better but does not add or subtract functionality. Because you write a test before you write the code the test in effect does double duty in that it both specifies and validates that piece of code. A test-driven approach can be applied at both the requirements level and at the design level, more on this later.
In May of 2014 I ran a mini-survey to explore how teams have adopted TDD in practice. There were 247 respondents from around the world, 40% of whom were TDD practitioners with an average of 16 years of experience in software development. I purposely gave the survey the title “Is TDD Dead?” so as to attract TDD practitioners. The goal of the survey wasn’t to determine whether people were doing TDD, with that survey title I would have hopelessly biased the survey, but instead to determine what teams were doing in addition to TDD to specify and validate their work. Not surprisingly the survey found that TDD practitioners are doing far more than just TDD to get the job done.
TDD and Requirements
A TDD approach can be used to specify detailed requirements on a just-in-time (JIT) basis throughout construction. Instead of writing a document to capture your requirements you instead capture them as acceptance tests which are added into your regression test suite throughout construction.
This practice is often referred to as acceptance test-driven development (ATDD) or behavior driven development (BDD). People will sometimes argue that ATDD and BDD are different, but the argument boils down to nuances that don’t seem to matter in practice-so call it whatever you want and move on. An ATDD approach is supported by a wide variety of development tools including Cucumber, Fitness, and JBehave to name a few.
Is TDD sufficient to explore requirements? Very likely not. Yes, ATDD is an incredibly valuable technique that I highly recommend, but it isn’t sufficient in most cases.
The survey found that practitioners who were following an ATDD approach were also applying other requirements-related activities:
- Sketches captured on whiteboards or paper (76% of respondents)
- Text-based requirements using a word processor or wiki (54%)
- Text-based requirements captured on paper (perhaps using index cards or sticky notes) (46%)
- Diagrams captured using modeling tools (such as Blueprint, MagicDraw, or Enterprise Architect) (18%)
Years ago in Agile Modeling we described how modeling and TDD fit together in practice. The observation is that modeling is very good for thinking through high-level concepts but usually rather clunky for specifying details. TDD, on the other hand, is great for specifying details but inappropriate for high-level concepts. As a result TDD practitioners need to adopt lightweight agile modeling strategies to enhance their TDD activities, something that comes out very clear in the survey.
A TDD approach can be used to specify the detailed design of your application code, database schema, or user interface (UI) in a JIT executable manner throughout construction. This is referred to as developer TDD or unit TDD and is typically done via xUnit tools just as jUnit for Java and PL/Unit for Oracle.
Not surprisingly the survey found that TDD practitioners are commonly doing more than just TDD to explore their designs. People doing developer TDD were also working on teams who were applying other design related activities, such as:
- Sketches captured on whiteboards or paper (79%)
- Diagrams captured using diagramming tools (such as Visio or Powerpoint) (40%)
- Text-based designs captured on paper (perhaps using index cards or sticky notes) (33%)
- Text-based designs using a word processor or wiki (29%)
- Diagrams captured using modeling tools (such as Enterprise Architect, Magic Draw, ...) (18%)
TDD and Testing
TDD is an aspect of confirmatory testing, the equivalent of testing against the specification (in the case the tests are the detailed specifications). Confirmatory testing is important but it isn’t sufficient as it assumes that you’ve been told what the requirements are, something we know that stakeholders are not very good at in practice. Disciplined agile teams realize that they need to also perform exploratory testing, the aim of which is to identify potential issues that the stakeholders haven’t told you about. Furthermore there are some forms of testing, such as integration testing within complex environments, which may be better performed but professional testers with experience in such activities. Sure enough, the survey found that in addition to TDD that agile teams were adopting additional testing strategies as well:
- Testers are members of the development team (62%)
- Some testing will occur at the end of lifecycle (41%)
- There is a team of testers working in parallel to the development team (33%)
To be successful at agile software development it requires discipline to identify, adopt, and then execute the practices described in this article. This article has just touched on a few of the practices, in addition to TDD, that agile teams are adopting. There is a plethora of software development strategies that your team may choose to adopt, and these strategies can be combined in many different ways. The Disciplined Agile Delivery (DAD) process framework captures several hundred agile techniques, providing advice for when and when not to adopt them. DAD has effectively done a lot of the heavy lifting for you when it comes to process, helping you to identify ways to enhance your approach to software development. Including, but not limited to, strategies around TDD.
- At Surveys Exploring the Current State of IT Practices I post the original questions, the source data, and my analysis of the results for all the surveys that I run. I am a firm believer in open research, and this is the highest level of openness possible.
- At Disciplined Agile Delivery and Disciplined Agile Consortium you can find out more about the Disciplined Agile Delivery (DAD) process framework.
- To find out more about TDD, you may find my article An Introduction to TDD to be a good starting point.
- The Agile Modeling site has a wide range of advice for effective modeling and documentation strategies, including advice for how modeling and TDD fit together in practice. The article Introduction to Agile Model Driven Development (AMDD) in particular should be a valuable read.
About the Author
Scott Ambler is Senior Consulting Partner with Scott Ambler + Associates, and specializes in helping organizations to successfully adopt disciplined agile strategies. He is the author of many books and a regular contributor to many magazines and industry conferences. Follow him: @scottwambler