ctapobep / blog

My personal blog on IT topics in the form of GitHub issues.
6 stars 0 forks source link

BDD and how it does NOT relate to TDD #8

Open ctapobep opened 3 years ago

ctapobep commented 3 years ago

There is a common misconception that somehow Behavior Driven Development (BDD) is related to Test Driven Development (TDD). I don't know who originated this rumor, probably same person who said that Scrum is Agile, and that DevOps is a person...

BDD

Anyway, there is an awesome article by Dan North (the author of JBehave and BDD) describing how BDD was developed. Long story short:

  1. Original idea behind BDD was about naming tests. Instead of saying "test this and that" we describe behavior: "the product works this and that". The body of tests stays the same.
  2. At some point this evolved into a tool to collaborate between BA, QA and Devs: BAs write requirements in a style which is compatible with tests, then AQA or Devs could reuse those as a starting point for automated tests.

Neither of these have anything to do with TDD. It's just at the time TDD was super popular, so my assumption is that Dan North tried to connect them somehow. But the connection is really awkward.

You can argue that when BAs write requirements in some BDD style that can be reused for testing - then it's somehow related to TDD, but:

TDD

TDD is surrounded with lots of misconceptions of its own. People tend to think that it's about testing, while in fact it's about splitting work into small chunks.

Let's take an example - there's a task and you need to keep lots of details in your head about it. You implement one part, then you switch to the next one, then you switch back and improve the 1st part and so on. Maybe somewhere in between you break something and there's yet another aspect that you have to deal with. All this leads to a pretty chaotic development process and you lose a lot of brain power switching between contexts.

TDD fixes this problem. Suppose you're writing HashTable:

  1. You first think "what's the minimum use case" and you write a test for it: ifNoElementsAddedSizeIs0. Then you go to your code and implement it (maybe for now just put return 0 in size()). This may be 1 use case out of 50. But it's written and covered.
  2. Then again you think about the next use case: sizeIsIncrementedIfNewElementIsAdded, you add a test and you add production code for it. Did you break the 1st use case in the meantime? That's what the tests will find out.
  3. You keep adding more tests like ifElementAddedWhichWasAlreadyPresent_sizeDoesNotChange and so on until you finish implementing HashTable. These steps will inevitably require refactoring, but the tests will keep you safe.

So TDD is not really about writing tests - it's about organizing your work so that the task doesn't overwhelm you. What should be the increment size? Up to you - whatever you think is appropriate, whatever is the number of things you need to keep in your head and not be overwhelmed.

Note that if you were to first cover all 50 use cases in tests and then you'll go and implement all of them at once - this would not be TDD. It would still be a Test-First approach though.