33

What is the relation of BDD and TDD?

From what I understood BDD adds two main things over TDD: tests naming (ensure/should) and acceptance tests. Should I follow TDD during development by BDD? If yes, should my TDD unit tests be named in the same ensure/should style?

3
  • 1
    BDD is a set of well documented TDDs (Unitests)
    – D.D
    Nov 25, 2015 at 8:33
  • Anyone keen to add an answer from the Behaviour Driven Design camp? From my point of view, these answers are all about the first few iterations of BDD. Successful applications of BDD these days are often closer to design, and may even omit automated testing completely, when appropriate.
    – Paul Hicks
    Nov 21, 2016 at 0:12
  • The difference between BDD and TDD is like the difference between Macroeconomics with Microeconomics. BDD = building an understanding of requirements using examples and optionally may be used to drive automated Macro tests. (agilenoir.biz/en/am-i-behavioral-or-not), TDD = writing micro tests to drive writing coding. The Agile Thoughts podcast covers these differences too: agilenoir.biz/en/agilethoughts/test-automation-pyramid-series
    – Lance Kind
    Apr 5, 2019 at 3:56

4 Answers 4

39

BDD adds a cycle around the TDD cycle.

So you start with a behaviour and let that drive your tests, then let the tests drive the development. Ideally, BDD is driven by some kind of acceptance test, but that's not 100% necessary. As long as you have the expected behaviour defined, you're ok.

So, let's say that you're writing a Login Page.

Start with the happy path:

Given that I am on the login page
When I enter valid details
Then I should be logged into the site
And shown my default page

This Given-And-When-And-Then-And syntax is common in behaviour-driven development. One of the advantages of it is that it can be read (and, with training, written) by non-developers -- that is, your stakeholders can view the list of behaviours you have defined for successful completion of a task and see if it matches their expectations long before you release an incomplete product.

There is a scripting language, known as Gherkin, which looks a lot like the above and allows you to write test code behind the clauses in these behaviours. You should look for a Gherkin-based translator for your usual development framework. That's out of the scope of this answer.

Anyway, back to the behaviour. Your current application doesn't do this yet (if it does then why is someone requesting a change?), so you're failing this test, whether you're using a test runner or simply testing manually.

So now it's time to switch to the TDD cycle to provide that functionality.

Whether you're writing BDD or not, your tests should be named to a common syntax. One of the most common is the "should" syntax you described.

Write a test: ShouldAcceptValidDetails. Go through the Red-Green-Refactor cycle until you're happy with it. Do we now pass the behaviour test? If not, write another test: ShouldRedirectToUserDefaultPage. Red-Green-Refactor til you're happy. Wash, rinse, repeat until you fulfil the criteria set out in the behaviour.

And then we move on to the next behaviour.

Given that I am on the login page
When I enter an incorrect password
Then I should be returned to the login page
And shown the error "Incorrect Password"

Now you shouldn't have preempted this to pass your earlier behaviour. You should fail this test at this point. So drop back down to your TDD cycle.

And so on until you have your page.

Highly recommend The Rspec Book for learning more about BDD and TDD, even if you're not a Ruby developer.

1
  • Can you just put comments? I still don't get it...
    – Honey
    Dec 23, 2016 at 22:10
7

My understanding of it:

  • BDD started as a rebranding of TDD to make the focus on behaviour clearer.
  • It gives more formal support (DSL and tooling) for a focus on behaviour and executable specifications.
  • BDD can now be seen as a superset of TDD,. It has grown over-time to encompass more of the requirements elicitation side of things, but still the development process side is a core part of it.

So to address the TDD done right part of BDD. BDD started as a change in language of TDD to make the intention of the process clear. Dan North's introductory article on BDD explains why focusing on the word behaviour rather than test is useful - it helps confirm that you are not just building the software right, you are also building the right software. This was always part of a good TDD approach, but Dan codified it a bit into BDD.


What I think BDD makes a bit more explicit than TDD, or at least formalises and provides tool support for, is this two-cycle / double loop / zoom-in zoom-out / outside-in approach. You first describe the expected behaviour of the feature (the outside loop), then zoom-in to the inner loop to deal with the low-level specifications.

Doubleloop TDD From http://www.metesreau.com/ncraft-workshop/

Gherkin in conjunction with tools like Cucumber and SpecFlow provide a way of writing those high-level feature specifications and then linking them in to code that executes the application code. I would argue that this is where BDD might 'feel' different from TDD, but it really still is doing the same thing, just with some added tool support and a DSL. Somewhat closer to 'traditional' TDD is using tools like rspec, nspec, spock. These feel a little more like the same process you'd do in 'traditional' TDD but with more behaviour-focused language.

In BDD in Action by John Ferguson Smart (highly recommended), he advocates for a double loop approach, starting with something like jBehave at the outer level executable specifications, then dropping into a tool like Spock for the low-level specifications.


BDD brings the concept of test-driven closer to the business stakeholders. Gherkin is designed to be business readable, and the idea of 'living documentation', i.e. automatically produced progress reports from your executable specifications is about giving feedback to the stakeholders.

Another part of BDD now, which is where it genuinely becomes something that incorporates TDD as part of a larger process, are the requirements elicitation bits and pieces. Ideas like Feature Injection, Impact Mapping, and Real Options are part of this side.

For the canonical answer on this, it might be best to go to Dan North again. If your team is all developers, then BDD = TDD. If your team involves a whole range of stakeholders, BDD is closer to XP, with TDD being one part of it.

3

What is the relation of BDD and TDD?

They are the same thing.

From what I understood BDD adds two main things over TDD: tests naming (ensure/should)

That's not really something BDD "adds". It's just a different convention that is meant to make it easier to teach and understand TDD.

The people who created BDD were all teaching TDD, and they noticed that the hardest thing to understand was that TDD has absolutely nothing to do with testing. Once students got over that hurdle, it went much easier for them. But, it's very hard to divorce yourself from thinking about testing, when the word "test" (or related terminology such as "assert") appears practically everywhere. So, they switched some words around.

But it's only the words! There is no actual difference between TDD and BDD.

and acceptance tests.

Acceptance tests are just as important a part of TDD as they are of BDD. Again: there is no difference between TDD and BDD: TDD done right is BDD, BDD is TDD done right.

8
  • In what way are acceptance tests an important part of TDD? Oct 1, 2011 at 14:46
  • @Idsa: they're important in that your code should not pass the tests that you think they need to pass, but the ones that the code is supposed to do. I think too many people get confused by this, that most unit tests are low-level and thus avoid the difficult problem of testing what the system was written to do overall.
    – gbjbaanb
    Oct 1, 2011 at 14:55
  • @Idsa: In the same way that they are important for BDD, of course, since the two are the same thing! The acceptance tests drive the outer cycle of TDD, the one dealing with features and users, as opposed to the more detailed inner cycle which deals with APIs and protocols and such. I think Kent Beck calls this "Zoom In / Zoom Out". You can, for example, easily see this in the JUnit test suite, which contains probably at least as many acceptance tests as it contains unit tests. Oct 1, 2011 at 15:03
  • Acceptance tests are an important part of TDD and BDD. But to say that BDD equals TDD is akin to saying TDD equals test-first. Unless you're allowing the tests to drive your code, you are not doing TDD (I used to know someone who was happy to write tests up front but argued that code should always be written as it would be if you weren't writing unit tests and that tests should be written accordingly). Likewise, unless you're allowing the behaviour to drive your tests, you are not doing BDD.
    – pdr
    Oct 1, 2011 at 16:25
  • 1
    @Idsa: Note that there are many wrong descriptions of TDD, which don't include acceptance tests. Those -- unfortunately pretty popular and pretty widely taught -- wrong descriptions are one of the reasons why the BDD people thought it might be a good idea to rebrand TDD under a different name, to avoid the confusion. Nevertheless, and it cannot be repeated often enough, TDD and BDD are exactly the same thing. Oct 1, 2011 at 20:02
1

It's the difference between writing the correct code (BDD) and writing the code correctly (TDD).

BDD is about specifying what the customer or user wants or needs in the form of one or more tests: The user has a problem they want the software to help them with, so how will we know that the software "behaves" the way it should and helps them solve the problem? We write a test (or a series of tests) that will verify when the proper behavior occurs. We then write code that makes the software pass the test(s), and so we know it behaves the way the user asked it to. Of course additional tests may define how the software should NOT behave, and those then also drive us to make sure the software complies.

TDD is about developers keeping code clean and adaptable by setting several rules:

  1. You cannot write any production code unless it is to make a failing test pass.
  2. You cannot write any more of a unit test than is required to fail (and not compiling is failure).
  3. You cannot write any more production code than is required to make the test pass.

This approach means that each test is specifying precisely what the next bit of code will do, giving you both comprehensive documentation and (once the tests pass) comprehensive code coverage. This level of coverage means that you can refactor your code (and your tests) at any time, so long as the tests all pass. This helps prevent technical debt and makes your code much easier to adapt as new requirements (in the form of tests) come in.

The major difference between BDD and TDD is that the behavioral tests in BDD are about what the customer is asking for, and these will probably be much larger than the single next little bit of code you're going to write. That is, they break TDD rule #2. Instead, a BDD behavioral test will probably fail for a little while we use TDD to drive the numerous bits of code that will make it pass. Once all the behavioral tests pass, we should be able to safely ship the code to the customer or user.

TDD on the other hand, helps developers ensure that the code is clean: with clear naming, limited duplication, short methods, etc., by giving them the ability to refactor it at any time. The advantage here is that when the next set of requirements come in, the code should be easily adapted to support them.

Not the answer you're looking for? Browse other questions tagged or ask your own question.