Why Should We Do Test-Driven Development? Part One

I want to explain why I find Test-Driven Development so important to modern software development teams.  There are many reasons, and it will take a few articles for me to go through them.  I’d like to start with a reason that may be the most important and is fairly easy to understand.

I have found that one of the most important things that TDD does, is that it protects an individual developer’s ability to create new code without harming the existing code.  When TDD is a team discipline, that team must run all of the unit tests and see them pass before they merge their code in with the rest of the team’s code.  When a developer knows that they may have broken something by what they add, it creates a high level of anxiety for a truly professional developer.  We often take pride in our work as developers and when our code breaks everything, it is very shameful to us.  Obviously, it is also very unproductive.  It is one of those hidden costs that makes software take longer to make and causes it to be less reliable for those who use it.  It can actually harm people when our new code breaks some of the old code that we didn’t realize would be affected.

It may be hard for those who aren’t software developers to understand the impossibility of merely reading the code in order to figure out if what we add will break something.  Even the most confident developer makes a typo.  All it takes is one letter or even a missing semi-colon in to harm the code.  I recently broke code by having the wrong case.  The letter was right but its case was not.  Trying to write code without a way to check it, is like having a job at which you must walk a tight-rope all day.  It’s clearly not sustainable.

The discipline of test-driven development, causes all team members to write their tests before they write their code.  This isn’t just a random and cruel requirement.  It’s a practice that ensures that every programmer’s intentions are both stated and preserved.  This may be the fundamental benefit of TDD.  It’s a way to communicate a programmer’s intentions to all future programmers.  That way, when a future developer makes a change, they add their new intentions and make sure all of the existing intentions are still being met.  In this light, TDD is fundamentally a discipline that enforces communication between developers.

It’s important to note that even when a programmer works alone, they often forget their own previous intentions for the software!  Our work requires that we focus.  It doesn’t take long for us to exceed our own ability to remember the details.  By practicing TDD, the intentions we preserve may be our own.

This is just one of the benefits I have witnessed over the years as I have practiced TDD.  It turns out that it also can improve our requirements process, serve as documentation, improve software design and promote the software’s internal quality, but this one reason alone would probably be worth the effort to me.



How to Communicate with Software Developers

If you are a project stakeholder and you have software that needs to be made, you might discover that it can be difficult to communicate your needs to software developers.  You may believe that you have communicated your desires, only later to discover that the developers have no idea what you mean.  So, how do you deal with this issue?  How do you communicate what you need to have done?

The most adequate software requirements I have seen, are test scenarios.  When these are provided before software is written, it gives a developer most of what they need to know to start working on the software.

Making test scenarios as requirements documentation takes serious dedication on the part of the customer representatives, though.  It requires that they go beyond providing a few sentences about the software.  They actually must pretend that they are using it.  It requires an adequate set of test data and a good imagination.  You must detail the actual steps you would go through and what you expect to see.  These are the procedures that will prove that the system is actually working in the end.

The basic framework for these scenarios is actually very simple.  They follow a three step pattern:

  1. Set up the starting conditions
  2. Perform some work
  3. Check for expected results

To write these down, you can use a pattern like this:

  1. Given a specific situation
  2. When something is done with the software
  3. Then some new situation is the result

I have come to call this pattern: “Given – When – Then.”  It has a formal name as well.  These descriptions are what we call “finite state machines” in software engineering.  A computer program can be defined as a set of these.  The great thing about them is that they don’t require a degree in computer science in order to make.  The only difficulty is that they take time, energy and attention to detail.

When you are first learning how to write these, I suggest that you start each step with the “Given,” “When” or “Then.”  Here’s an example:

  1. Given a user that has a bank account and has already put their ATM card into the ATM and used their pin to access their account.
  2. When the user requests a balance.
  3. Then the ATM shows the user’s balance to the user.

It may look easy at first, but it usually becomes evident after you start writing these down, that things have not been completely thought through.  For instance, notice that in the given part of this ATM scenario, you haven’t really described how the ATM should use the PIN yet or when the card should be taken.  Then there’s the possible fraud cases.  You have to know when to deny access too.  After you get started, you may feel like it’s just too hard, but don’t give up.  What is actually happening, is that you are flushing out issues before a software engineer is employed.  This hard work pays huge dividends.  It makes it possible to communicate with software engineers in a way they actually understand.

Although every detail that is important should be described, not every Given-When-Then has to be done before software development begins.  This is one of the biggest benefits of agile practices.  It’s important that developers use a method of development that will support changes to requirements, though.   Test-driven development and the creation of automated tests for your scenarios make that possible.

You might be thinking that you really should write down all the test scenarios before you have a developer start working.  The problem is that we usually forget important scenarios and have to add them later anyway.  It’s good to detail as many as you can and then prioritize them.  It’s usually the focus on priority that will benefit you more than completeness.

So, I challenge you to try this with a single test scenario.  Write out your scenario using the Given-When-Then style and take it to a software developer.  You will probably be amazed at how fast they understand what you’re asking for.