What (almost) Everyone Gets Wrong About TDD & BDD
While I was creating coding skills for Claude, it decided to tell me one day that what I was trying to do in the name of Test-Driven Development (TDD) was more like Behaviour-Driven Development (BDD). Typically, it was confidently wrong. Unfortunately, this is primarily because most people are confidently wrong on this topic too.
Let me explain.
TDD: modernising a lost art
Kent Beck’s TDD was inspired by the lost art of creating input-output examples by hand, and changing the logic until the machine produced the same output.
The earliest published reference to this that I’ve been able to find is in D.D. McCracken’s Digital Computer Programming, 1957. He called them “hand-calculated check cases” — examples worked out by hand before any code is written, used to verify behaviour once it runs.
Kent has talked about reading the same idea as a child, in an old programming book around the house.
“I remembered reading this and tried it out. That was the origin of TDD for me”.
He’s always been careful to call TDD a “rediscovery”, not an invention. Perhaps it was McCracken’s book that he read (although that wasn’t the only book that described this approach).
TDD: more than just the Red-Green-Refactor loop.
McCracken’s 1957 equivalent talked of how important it was that the “customer prepare the check case, largely because logical errors and misunderstandings between the programmer and customer may be pointed out by such procedure”.
Kent’s book ‘eXtreme Programming Explained’ in 1999 did the same, it talked of both customer tests and unit tests, with one example reading:
“When we run the export station, the values in the export record should match the values in the bins.”
In his 2003 book “Test-Driven Development by Example”, the focus was on the red-green-refactor loop. However, in the Mastering TDD section near the back of the book, he took things further. Here Kent talked of both application-level TDD (ATDD) and “programmer-level TDD”. He also highlighted the challenges of adopting both at once:
“Mixing up the rhythm of red/green/refactor, the technical issues of application fixturing, and the organizational change issues surrounding user-written tests is unlikely to be successful. The One Step Test rule applies. Get red/green/refactor going in your own practice, then spread the message.“
This wasn’t distinguishing a separate approach, it was about pragmatic adoption of the whole approach — both acceptance-test and unit-test levels of TDD.
But for ‘reasons’ the mainstream diluted TDD to just be what he called “programmer-level TDD”. Somewhat understandable because up to that point I don’t think we yet had the framing necessary for the majority to receive these ideas clearly... And even if we did dilution and distortion of ideas is just what happens when concepts go mainstream.
At around these time, there was someone else trying to solve this problem.
Enter BDD: originally a reframing of TDD
Daniel Terhorst-North, who coined the term BDD, found that “people’s misunderstandings about TDD almost always came back to the word ‘test’” — so he changed it for ‘behaviour’.
This removed the need to first overcome what people thought of as a test and shifted the focus to conversations about specifying behaviour with a self-verifying executable specification — exactly what many of us involved in discussions about TDD in the early 2000s had come to appreciate about its intent.
This change in vocabulary meant that you didn’t have to first break down an old mental model around the concept of testing. Instead, you could start a fresh conversation.
The shift in language was:
“so profound that I started to refer to TDD as BDD.”
His own words from his 2006 article ‘Introducing Behaviour-Driven Development‘.
Dan used this as an opportunity to capture many of the lessons and insights he learned about TDD the hard way and make them explicit. Among them the outside-in flow from customer tests to internal ‘programmer level’ tests.
The shift in language was thorough. Tests became scenarios or examples; unit tests became specs, “Assert” became Then and should — the latter not dissimilar to the examples in Kent’s 1999 eXtreme Programming book.
Calling it BDD had a couple of other benefits too. It was quite common at the time for coding and testing to be carried out by quite distinct roles with little to no collaboration between them. Many developers would not engage with a conversation that led with the word ‘test’. That wasn’t their responsibility, not for them, at that time.
The other benefit was that Dan could explain TDD in a way that nobody could argue with. Nobody less enlightened could say “that isn’t TDD” because he wasn’t calling it TDD.
The practice stayed the same; the language changed, and in doing so removed barriers to both conversation and comprehension.
BDD has, of course, evolved beyond just a reframing of TDD with the emphasis on the shared understanding arising from conversation, over tooling or implementation. Today, BDD is more a re-framed sub-set of XP than just a reframing of TDD. But its grounding as a rearticulation of TDD’s intent, remains.
The irony is that the outside-in aspect of TDD, that got lost in translation, was something that BDD tried to make explicit and intrinsic to the approach. Yet BDD, for most, has been reduced to just customer tests written with Given/When/Then.
The outer and Inner loops solidified
Finally, in the 2009 book “Growing Object-Oriented Software Guided by Tests” (or GOOS book) by Steve Freeman & Nat Pryce, the terms outer and inner loops of TDD solidified.
While this came 3 years after Dan’s article, Nat and Steve were early adopters of TDD. They were totally comfortable with the ‘test’ oriented language of TDD, and chose to stick with that nomenclature.
While this probably wasn’t the first time this shape was drawn, this was the first book I remember seeing TDD illustrated this way.
The GOOS book was the ‘Mastering TDD’ section from TDD by Example, finally expanded and realised.
Now what?
At the end of the day, if you are working outside-in, one executable example at a time (a.k.a. Specification by Example), it really doesn’t matter whether you call all or part of it TDD and/or BDD — as long as you are getting the benefits from it.
I admit that I do cringe slightly every time I hear someone say ‘shall we write the BDDs’ or ‘correct’ people when they include the outer loop of TDD and say “you’re thinking of BDD”... But most of all, I just don’t want people to miss out on the richness of what these different framings gave us...
Some great ways to articulate one of, if not, the most impactful changes to common ways of working in modern software engineering in the last 30 years.
If anyone has any corrections where I’ve got something wrong in this article, I welcome them... But I would appreciate more than just personal opinions in that feedback — for 3rd parties, please provide quoted facts and sources. Those tagged in the article, are most welcome to tell me their 1st person views of course. Thanks in advance.
Antony Marcano also available as a consultant for hire, working with leadership, and engineers (and sometimes even takes on interim engineering leadership roles), to help people and companies achieve greater things.



