How BDD focusses on the ‘why’

Today i got talking with somebody who was unconvinced of the benefits of behaviour driven development. I hope i’m not misquoting them, but they seemed to be saying that BDD doesn’t tell you why something happens, only what happens.

This person also said that BDD doesn’t encourage you to code correctly. That i agree with. You can code poorly with any test tools or development framework. The only thing that’s going to encourage you to code cleanly is your own standards, or those that are instilled into you by requirement, or pair programming, or code review.

To me, the focus on the why is a key difference of BDD as opposed to TDD. Here’s an example for comparison:

Test First Development tells you that you’re going to use an Array of names and it’s going to receive the shuffle method. You write the test because you’ve already decided that’s what you’re going to do. It is brittle because a change in the code will require you to rewrite the test.

Test Driven Development says that somehow some names are going to be input, and after the process they’ll come out in a random order. It doesn’t necessarily mind whether you use an Array, Hash, a shuffle method or write your own randomising function. You let the tests drive you to make those decisions when you need to.

Behaviour Driven Development tells you about me as a key stakeholder, and that i want to draw names in a random order, so that i can assign prizes fairly. It tells a story about the people entering, explaining in natural language that the names are drawn out of a hat, and when they are, the first randomly chosen person picked gets the first prize, and their name is put aside so that they don’t win another prize. How you implement the details to achieve this behaviour is entirely up to you as a developer. But you should understand quite well what you’re expecting to achieve, and why.

Okay, i know, it’s a horrible example because it’s quite difficult to test for randomness. Given an unbiased coin / When i flip the coin / Then i should get … either heads or tails … Anyway, hopefully those examples show how i consider the test methodologies to differ.

My mentor Enrique recently helped me to understand BDD, particularly Cucumber scenarios, as documentation of the understanding between the client and the developer. It just so happens that you can execute this documentation to help you write your code, and continue to use it for regression testing.

Now i pass over to you, my readers! Are your opinions different from mine? What have i missed out, misunderstood, or misrepresented? I’m not an expert here! Fortunately, you don’t need to be a BDD expert to benefit from using it! :)

14 comments on “How BDD focusses on the ‘why’

  1. Hi,

    I definitely agree that TDD can create brittle tests when you’re really getting in to the guts and white box testing. It creates a very tight shrink wrap around the system which is great for regression and enforcing polices in code throughout tiers.

    However, when I began thinking about BDD’s Given/When/Then actions, doesn’t the Given/When part of this imply that your specifying inputs and set-up, thus also making the test aware of some of the guts of a SUT, making it as brittle, or tightly coupled if you will, to the code?

    Regards, Martin (@martinblore)

    • Hi Martin, that’s an interesting observation. Over the years i’ve definitely found some brittle ways of writing scenarios, and i’ve learned a lot. I don’t think i’ve really experienced the specific problem you’ve mentioned, but i look forward to hearing what other people think about that.

  2. A wonderful write up illustrating the differences between a set of definitions that are consistent and tidy. It provides a good basis for further constructive discussions on the topic. I am sure there will be people that disagree with a detail or two of the picture you paint above, but what really matters is that there is a reasonable definition set such that everyone involved in a TF vs TDD vs BDD conversation can speak the same semantic language.

    Before reading this post I couldn’t put my finger on the difference between the first two in my own mind but the picture you paint is consistent with experiences that I couldn’t/didn’t verbalize. Though my previous thoughts on TDD and BDD strongly agree with your model above.

    What are your thoughts on using Development instead of Design (or vice versa)? Does it matter?:) I am not sure how much it matters, but interested in others views. Challenge: convince me one way or another with good arguments (no trolls people) if you are so inclined.

    (Forgive my American spellings [and punctuation]. I can never remember which words are ise or ize in my mother tongue nor which punctuation rules are which.)

    • Hi Susan! No worries about the spelling: making yourself understood and communicating your thoughts somehow is far more interesting than spelling and punctuation! :)

      Thanks for your comments about this being a good basis for further discussion. I’m glad it helped to clarify a few thoughts in your mind.

      For me there is a polarity of two extremes: Big Design Up Front (pretty much synonymous with waterfall development) and No Design Up Front (let TDD make all the decisions for you).

      BDUF is restrictive because you cannot predict at the beginning all the little problems and nuances you will come across, and often you actually have to experience something to know what it really feels like to use, and to discover how to make it better.

      NDUF is probably an even worse extreme, because you’ll be floundering, making decisions haphazardly, without a big picture to guide you through with the foresight of what might be coming next. I think it was Uncle Bob who said, If you don’t know what you’re doing, TDD won’t help you get there!

      So obviously a happy medium is required. Just the right amount of up-front planning so that you have a clear direction and awareness of what you want to discover as you go along. And of course, tests to help you refactor often, and keep the code as clean and lean as possible at all times.

      That is a gigantic soapbox i’ve just found myself precariously perched on top of! Someone bring me a ladder and help me get down?! ;)

      • Actually I should have clarified earlier. I was referring to using the term Behavior Driven *Design* as opposed to Behavior Driven Development (same case was made for using Test Driven Design as opposed to Test Driven Development as well).

        In late 2006/early 2007 when I first started investigating BDD, transferring from the TDD world, I remember reading an article on a BDD wiki site that I can no longer find. The crux of it was that by using BDD(esign) instead of BDD(evelopment) (using Sapir-Whorf hypothesis as justification) forced engineers to focus on the APIs and overall design of the application incrementally. The idea is that it would yield a more holistic and consistent design. I had thought it was a Dan North article, but upon searching his blog I see no mention of this.

        Thoughts? I haven’t not heard this reiterated over the years since, so I wonder if there were any experiments/research conducted to show no difference (or even the contrary) or not?

  3. I’ll start with a confession: try as I might, I really don’t get the difference between TDD and BDD.

    Both are concerned with the specification and verification of the behaviour of some software.

    Both explicitly make the desired behaviour drive the implementation (using Given/When/Then or Arrange/Act/Assert, and by writing the specifications before the code).

    Both provide a readable and executable definition of desired behaviour to check for regression etc.

    It seems that perhaps the distinction is that TDD is code-focussed, and that BDD is system-focussed but this is a false distinction IMHO. TDD is a practise that works at all scales (see Nat Pryce for more on this). In fact, TDD at the system scale considers a wider scope than just end-user requirements. Or at least it makes it clear that Ops and live-support people are end-users too.

    So, most likely, I have misunderstood something along the way, but essentially I feel that BDD is just well-written, system-level TDD. What do you think?

    And, to address Susan’s question about the second “D” – I’ve found them to be used pretty much interchangeably by most authors. I think that this is natural and healthy, that development very much is design. That said, I tend to use “design” myself, as good design is an often-ignored benefit of TDD which I like to remind people of.

    • Matthew, i think i agree with you. When you put it like that, there really is little difference between TDD and BDD. In the end they do both achieve more or less the same thing. I don’t think of one being better than the other, i suppose i just feel that BDD suits me better.

      The language you have used: specification and behaviour is very much towards the BDD language. Sometimes people get hung up on the words ‘test’ and ‘assert’. They sound a bit final. If a test fails, then you might think there’s a bug. Or the test is wrong.

      Simply by changing the language a little, to ‘specifying’ and ‘describing’ and ‘it should’ and ‘it behaves like’ … this may allow a little more creative thinking. Something is no longer either working or broken, but now we have the opportunity to question again, “Should it really behave in that way, or did we misunderstand something before?”

      It sounds as though you may be closer to BDD than you realise :)

      • You both just made me remember how BDD grew from TDD. Some of the points that Dan North (@tastapod) was first presenting on InfoQ a while back were somewhere along the following points.

        BDD is TDD done right. TDD had all the right values of what is was trying to achieve, but its Vocabulary was inaccurate. Test-Driven-Development was simply a bad description of what it was trying to teach.

        It started getting coined as Test-Driven-Design, then eventually BDD, that set down the rules that helped peoples minds think of behaviour of a system in an easier way. People who came to TDD had a harder time realizing the values through its vocab and the way tests were named and the thought process etc. People who did TDD long enough matured and began to fall naturally in to a BDD way of thinking. So BDD was realized and became a staple pattern.

      • Ah, now it’s all coming together. Enrique just made that point too, about BDD being TDD done right. And it is about vocabulary and how that makes us feel about what we’re doing. And now you’ve helped me to better understand Susan’s point about Development vs Design.

        Thank you! :)

  4. I would add that in either case test after, TFP, TDD or BDD we should always test behaviour and not implementation.

    • Yes. In the end, we are always testing behaviour. A system works or fails based on the behaviour it exhibits. I think BDD just tries to make that a little more obvious in the way it approaches things, and the kind of language it uses.

  5. Nice writeup aimee!

    There is a common misconception here though.

    TDD can be made test-first or (hopefully not) test-last. Test-first and test-last only stress when the testing in the cycle happens (as their names imply). Being more of a purist I would argue though that testing last really is TDD. As the name says, the tests should drive the coding effort.

    When it comes to BDD and TDD there is little difference. J.B. Rainsberger said a couple of years ago that BDD is TDD done right. Basically by changing the name of the practice we could get practitioners to focus more on the desired outcomes and therefore write less brittle tests.

    The trick here is the name behaviour as opposed to test. When using “test” you imply that you are testing and not designing your application, which opens different tensions.

    • Wow, thank you Enrique. I’m glad this is turning into a discussion where i can learn more. I felt i wasn’t quite right, but i put it out there as a sort of “This is what i think, do you agree?”

      I’m glad to hear you agree that TDD and BDD have little difference. When Matthew (marrowboy) explained it in that way above, i thought, “Actually yeah, i think you’re right”. It’s all about input and output, and the behaviour that describes how things transform from one to the other.

      Many thanks for sharing your thoughts.

  6. Anything which improves the probability of writing good code (and good tests) is helpful.

    It is *possible* to write great unit tests without using TDD, but it is really hard. The TDD process is a forcing function which inherently exposes design and implementation flaws (such as coupling) which aren’t otherwise obvious to most developers.

    Similarly, it is *possible* to plan an optimal test suite without using BDD, but BDD makes the decisions about test scope, focus and granularity much more straightforward.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s