TDD and BDD: The Ultimate Answer to Life, the Universe, and (Testing) Everything
Wherein all will be explained, answered, fixed, thoroughly tested and approved. Ship it!
Test Driven Development aka TDD, and Behavior or Business Driven Development aka BDD, are both approaches to automated testing, originally stemming from Agile and Extreme Programming in the 2000s. It’s taken a while, but today these approaches are widely used and recommended.
Thing is, they sound similar, and they can be similar, but there are important distinctions.
Let’s dive in and see if we can sort the dolphins from the fish.
Writing Your Tests First
Historically in software, we code up a bunch of functionality, get a prototype going, maybe showcase it a few times, add a few more features, rush towards an initial release, and somewhere along the way we push in some automated tests.
Or maybe, we just kick the bucket down the road until stuff starts breaking or customers complain. Once the pain gets painful enough, we motivate ourselves to write some tests. That’s sufficient for a while … eventually though the tests break, we don’t notice they’re broken, bugs get out to production, customers complain again — possibly about the same bug they complained originally, ie. a regression — bosses yell at developers and testers. Freshly motivated, we fix our broken tests, write a few new ones, congratulate ourselves for all the hard work done, and get back to a relaxing bath.
One day, someone somewhere came up with the idea: what if we developed the tests first ?
It might look something like this:
Now it probably seems counterintuitive, to write tests before actually starting work on a feature. It does take additional time in the short term, but there are several benefits:
- When you’re done, you’re submitting both features and tests with the same work order — no need to procrastinate, testing is already done !
- Since you’re deliberately thinking about testing early on, you will (hopefully) come up with more and better test scenarios.
- As this practice takes hold, you’re encouraging a test and quality oriented team culture.
I love TDD, and although I haven’t used it on every project, I’m enough of a fan that I’ve actually written a TDD engine of my own. It’s called Futo-Spec — check it out !
Okay, so if writing tests first is TDD, what is BDD ?
The Business Philosopher
I’ve seen BDD translated as both “Business Driven Development” and “Behavior Driven Development”. For my purposes, the terms are synonymous. We are talking about the behavior of customers and users as it relates to code for a business, or business use cases. So, either translation works for me.
Fine, but what the heck are we talking about ?
BDD means that test cases are defined or specified in a way where the specification itself drives your test code. Your work spec is also the first layer of your actual test repository. In my experience, this is done with the tool Cucumber, and its English-like top layer syntax called Gherkin.
The top layer looks something like this:
Feature: Donuts
Scenario: Glazed donuts
Given I make a fresh run of donuts
When I add glazing
And I serve to customers
Then customers are ecstatic Scenario: Whole Wheat Vegemite donuts
Given I make a run of whole wheat sugar free donuts
When I add vegemite
And I serve to customers
Then customers burn down my bakery
This “feature file” gets mapped to a second layer called “step definitions”, which in turn leverage bottom layers, which do the actual work. An example stack is here: Feature File, Step definitions, Screen models.
By using this layered approach, we are adding context. In a Cucumber stack, it is far easier to understand when, how and why a test has failed.
What is my framework if it’s not BDD or TDD ?
We have a term “waterfall” to describe something not Agile. What about automated tests ? If we aren’t using TDD or BDD — if we aren’t writing tests first, and we aren’t using Cucumber specs as our test engine — what do we call this ?
Honestly, I haven’t heard a term. Perhaps “pre-Agile” is accurate. We could call it “functional non-BDD testing” maybe. Maybe “flat testing” is good, since instead of a layered BDD engine we have a flat JUnit style test where our top layer is still very technical without a lot of abstraction.
“Flat testing”, then ? Shall we coin a term ?
What’s the difference ? Why is there a difference ? Can you do both ?
TDD is a process which writes automated tests before application code. BDD is an approach which incorporates your work specification, as the top layer of your test execution stack.
Why is there a difference ? Well, I would say software is complicated and prone to breakage, so multiple approaches to testing a product is a Good Idea. Plus, if TDD is generally done by developers, then IMHO additional attention given to testing by developers, is a Good Thing.
Can you do both ? Absolutely, and I’ve worked on several projects which do. TDD tends to be the domain of a development team, and BDD tends to be more relevant to a QA team as they try to match specs from product design and executives, against the product they’re actually testing. The projects I’ve worked on which used TDD and BDD, were robustly built and had the metrics to match. Plus, the engineering department had a noticeable testing culture.
To me, using both makes a lot of sense.
Wrapping up: Tech stacks come and go, but Fundamentals rarely change
Clearly, your author is a fan of both TDD and BDD. That said, fundamentals of software quality don’t change much. We need to be well-organized, we need to track execution, we need to be proactive, think outside the box and anticipate problems.
Automation is one tool for quality, but quality is more than automation. People are important, process needs regular review and revision, pain points need to be continually identified and resolved, and a strong testing culture pays for itself many times over.
Happy testing !