I’ve been mulling over my dissatisfaction with BDD, and I’m finally in a position to write down my thoughts.
In short, BDD doesn’t actually seem to be a coherent thing. There are many different perspectives on it, and many different tools with slightly different focusses. The only consistent thing is that the word ’should’ is required to be used anywhere that you would traditionally have used ‘assert’.
To be clear, my argument isn’t with the tools that have been developed: I’m not sure I have a need for ScalaTest or easyb or RSpec or Cucumber, but I think they’re interesting and I hope that future development will lead to something I find compelling. My problem is with the definition of BDD itself.
BDD started off being touted as a replacement for TDD. TDD was too hard, people confused TDD with a testing methodology, people didn’t understand TDD was about design, tests were too hard to read: so the BDD inventors and proponents suggested. Some of this may have been true, there are many people who fail to grasp that TDD was primarily, but not exclusively, about design. Dan North, Dave Astels and others decided that the way to reduce confusion was to change the name; which always reminded me of the way Borland decided to improve sales by changing their name to Inprise.
So here we have it, BDD is a replacement for TDD, now it uses specs and the word ’should’ rather than tests and the word ‘assert’. I thought it was a bad idea at the time because you don’t make things easier for people to understand by having more than one way to say things.
assertEquals(oneWayToDoThings(), "good");
many_ways_to_do_something shouldBe 'bad'
I have no doubt that the creators of BDD and RSpec had good intentions. I have no desire to challenge their integrity or their creativity.
As time has gone on, BDD has morphed into a creature that is neither fish nor fowl. BDD specs have morphed, in many cases, to be ‘executable requirements specifications’ which is a laudable goal, but leaves a number of holes.
If a spec is an executable requirement then it is written in customer language. If it is written in customer language then it is of no use as a tool for driving design of classes, methods, objects and functions. So, if this is the home of BDD then it isn’t a replacement for TDD it is something that lives alongside TDD. Mention this to a BDD proponent, though, and you get an argument. You can write specs that cover the same ground as unit tests. Yes you can, but what are the advantages of doing so? You’ll have wordy, obfuscated tests carrying the baggage added to make BDD more palatable for customers and, you still miss out on many of the benefits of TDD.
TDD, as a design methodology, forces you to write code that is used by two different clients: the tests and the final application. This is one of the ways that it helps promote flexibility. It gives you an early look at ‘how exactly am I going to use this class/object’. DBB frameworks don’t look or work like the code that will be calling the final code, so there really is no benefit here. Take easyb as an example, it doesn’t even use the same language as the code you’re writing (assuming the common use case of using easyb as a BDD framework for Java development).
TDD highlights pain points when writing tests, if it is hard to write a test for, your code probably needs a little work. BDD frameworks such as Cucumber, can quite happily support specs written in terms of ‘the system’ or ‘the application’ and you have to write grotesque code to make it work under the covers. This doesn’t make Cucumber a bad tool, just the wrong tool for the job of designing code.
So what is the output of BDD: User Acceptance Tests? Functional Tests? Unit Tests? System Tests? A system design? The design of individual units? It depends on who you talk to.
I’ve seen specs that are written from a customer point of view, useful as user acceptance tests. I’ve seen these mashed until they talk about an application in terms of controllers and pages and objects, making them useless as user acceptance tests because they’re not what the user agreed to and they no longer understand them well enough to re-agree to them. They’re also sub-optimal as drivers for design because they’re based on the implementation assumptions of the end user and they’re constrained to be about the subject matter that the user was originally talking about. This leaves lots of areas undefined where you need design but don’t have explicit user requirements because they just want it to work. The users will not tell you that they want to ensure that you have properly nested resource de-allocation blocks in your JDBC code because that’s not their domain. Do you need to have it? Yes, absolutely. Do you want it to work every time. Yes, absolutely. Will a badly designed solution make your code a pain to work with forever, yes absolutely.
So what happens? Developers have to write more specs, for things that users actively don’t want to know about.
I’m not convinced by BDD as a means of writing functional specifications either ( this doesn’t include User Acceptance Tests ). The best functional specs I’ve seen were elegant documents that used text, screenshots, charts, tables, diagrams, flowcharts and even embedded sound files to describe as concisely and accurately as possible the users expectations. Constraining these documents to a structured textual format is, at the moment, a bad idea. We’re reinventing Knuth’s Literate Programming ideas of the seventies, only we’re trying to impose it on clients and analysts too. There may be a future here, but I don’t think we’re here yet.
Particularly egregious offenders here are those cases where the functional specification is written in embedded strings in a document that is otherwise code. Conflating two completely different documents, and levels of abstraction into a single chimera-like whole that serves nobody well.
Ten years ago, I worked for a company where all development was done in UML and we forward generated the code from our diagrams. This didn’t work well, it was slow and painful but ‘technically’ it was possible so those in charge kept pushing the idea. Writing functional specifications using BDD frameworks is ‘technically’ possible but that doesn’t make it a good idea. Not here, not now.
We’ve learned new ways of building tools, and we’re looking for ways to leverage them. BDD isn’t AN answer, so it certainly can’t be THE answer.
Recent Comments