The first reason that I gave for doing test-driven development in part one of the series, is that it enforces communication between developers about their intent for the software they have written. It ensures that those intentions stay in place as new software is added to the system over time. Another important benefit of test-driven development is that it helps us document our intentions.
It’s important for professional developers to understand that they have a responsibility to document the system’s behavior. Software isn’t just for computers to read. It’s for other programmers and stakeholders too. One of the benefits of a disciplined agile approach to software engineering, is that it naturally relaxes the need for some of the documentation. One of the reasons that this is true, is that it is assumed that a full set of tests are going to be produced that form the specification.
Without TDD, where will the design be documented for future developers to read and understand? It is true that the code is there, but the code doesn’t preserve the intent of the original developer. It merely satisfies that intent. I can see how it would be possible to preserve the intent in declarative code, but object-oriented and functional code is far more difficult to be sure about. What if a future developer considers part of the existing code to be a side-effect? That future developer will preserve what they perceive to be the original intent as they refactor or port the code to a new design. I have actually seen this cause a production error in an area where tests were lacking, even on an a team that was trying to do TDD.
Another issue is that without a complete set of requirements documents, the team eventually forgets how the system works. This seems to happen a few short years. Eventually, even the most brilliant minds on the team start to forget what the system does in certain important state transitions. The system gets more complicated as new features are added and, at the same time, we start to forget the things we did in the first few iterations.
If we are going to take hold of the privilege of agile software engineering, then we must also embrace the responsibility of it. If we decide not to do TDD, then we had better plan on going back to written design documentation. We must also keep that documentation current as changes are made or else it won’t help. As you probably imagine, that is going to slow the team down. It’s difficult to say that a team is “agile” when it chooses to go slower because it doesn’t want to perform the discipline of TDD. If it decides to not do TDD and not document the design, I would question whether the team is even professional. If we are to be both professional and agile, then I know of no other way to deal as efficiently with requirements documentation, than to maintain the discipline of test-driven development.