Walk around the cubicles of most software development groups in large corporations these days, and you’ll increasingly hear developers using terms such as Test Driven Development (TDD), Behavior Driven Development (BDD), and red/green/refactor. So what's this all about?
The buzz around these terms is on the rise, but these practices have been around for more than 15 years. What's new is that larger companies are beginning to embrace them, and the main reason for that is undoubtedly the move by these organizations to adopt agile and DevOps practices. In fact, some developers go so far as to say that you're not agile unless you're doing BDD. Another factor at play is the fact that the type of modern software most teams are now developing, such as mobile apps, web apps, and micro-services, fit nicely with TDD/BDD practices. But while there are many benefits to TDD and BDD, the biggest reason you should be moving in this direction is that it's the only way to stay competitive in a customer-centric development world.
Any group on the path to DevOps and Agile should take a look at these “test-first” methodologies. Here's why, and the benefits of each.
Test-driven development (TDD): Fail first by design
When you follow TDD you use tests as a way to design code by creating the test first, before actually writing production code. You then try to make the test pass by creating production code that fulfills the test. This is usually a five-step red/green/refactor process, where red indicates a failed test and green a passing one. It goes like this:
- Write a test (also called a specification)
- Run the test and show that it fails (red)
- Write the smallest amount of production code possible that meets the needs of the test
- Run the test until it passes (green)
Why fail first? The main advantage of working from a failing test first is that it keeps developers honest about where the defects are. In many cases, they get to see the defects before they've even written the code that will produce them. With this process, developers are also able to think things through a bit more, and it helps them to proceed at a more honest pace, so that they’re finding and fixing defects in a much tighter feedback loop than if they had to wait days for your QA teams to run a test and then give feedback. In essence, developers are fixing the problems while the code is still fresh in their minds.
Done right, TDD forces developers to start thinking about the testability of their code as early in the development lifecycle as possible. The more testable the code, the easier it should be to automate and obtain the feedback your team needs when rapidly deploying software to your customers.
Behavior-driven development: Taking the user focus
While TDD is a low-level approach, written from the perspective of a developer, BDD is more of an agile, “as a user” approach. Here you’re writing tests as stories. The focus is on the user and around having a discussion before creating a single line of code. When it comes to uncovering bugs, you can’t get much earlier in the development process than that.
The core BDD concepts come out of Eric Evans' 2004 book, Domain-Driven Design, and the idea of a domain-specific language. A DSL is a way for teams to talk about requirements and tests using the same terms as their users. This makes it easier to have a conversation between technical and nontechnical users in order to uncover any ambiguities or misunderstandings of requirements before the developer writes any code.
Another benefit of BDD is that when you write your scenarios down in your DSL, you use Gherkin, an English-like syntax. Gherkin provides a structure for writing your tests in a way that all of your team’s stakeholders can understand, and you can use it to create automated tests that read more like documentation, as opposed to a hard-to-understand programming language.
The real value here lies in better communication. If you work for a large company, with teams spread out across the globe, communication is one of your biggest roadblocks to success. With BDD, you get the side benefit of executable specifications, but the primary benefit is the ability of your teams to collaborate and communicate better with one another.
This approach also helps to ensure that you're building a quality product right from the start, as you go. That's the main advantage of test-first development. The earlier a defect is detected, the cheaper it is to fix.
Time shifting creates time savings
Many engineers complain that a test first-driven approach is too time-consuming. In fact, I recently heard a development director say that “rock star” developers should be focusing on writing code and getting features out the door, not on testing. This type of thinking is misguided.
I was speaking recently with Matt Wynne, author of The Cucumber Book, and he brought up a great point: With TDD and BDD, we are shifting where developers spend time in the development cycle.
For example, if you use TDD, the total elapsed time from when an idea comes into the team and when it leaves as working, defect-free software will be greatly reduced. Why is that? Although the team will spend some additional time analyzing and test-writing prior to the actual development work, they’ll save more time later in the process by not having a long quality assurance (QA) stage.
This helps to avoid what most teams expect: a long QA stabilization period once the development work has been done. The time that you invest upfront pays dividends once development is finished because you don't have that rework cycle that teams are so used to having to thrash around in at the end.
Yes, TDD/BDD will slow down your team’s velocity at the outset, as they slow down and learn how to write those tests. But they’ll eventually see the time savings when, after the code has been written, there’s barely any QA work to be done.
Test-first is customer-centric
We’re now living in a customer-centric development world, so companies are trying to be more user-centered in their development approach. Customers also have higher expectations of the technology they use, and meeting those expectations is critical. In this new world order, organizations that focus on agile, DevOps, and test-first strategies such as TDD and BDD will have a competitive edge over those that do not. That's why test-first methodologies are more important than ever.