Although I have now begun to play with writing high level specifications with NBehave I must admit that I'm not getting much further with understanding BDD in general.
I thought I should put my questions into a blog post, I guess its more of a brain dump than anything else though.
Is BDD just better TDD?
Its tempting to view BDD as doing TDD well. In reality though there are lots of ways to practice TDD but BDD is slightly more specific, such as the way it drives for an outside-in approach.
Having said that I think you can use BDD without buying into the whole Mock Roles, Not Objects approach but it is interesting that BDD is pushing that style of working. I've tried it out and it can have advantages but unsurprisingly it also has some serious problems.
Outside-in can mean many things but I like the definition from XUnit test patterns. Anyway even if you do practice outside-in you don't necessarily buy fully into the approach where you start with the GUI (or slightly below) and mock your way to all your collaborators (as described at Wikipedia or Mock Rokes, Not Objects).
If you practice DDD then you probably focus on the domain early, often then using classicist style testing practices (I've blogged about this before). If you do use mocking its probably when testing services and your probably not using it to definite ISP compliant role interfaces (or maybe you are, is it working because I am interested).
I think you can also find value in outside-in testing but this time starting from the public interface to the domain/application. You can start with a high level test and then start using TDD for the details, as discussed here. Once all the code is written. That doesn't preclude you using Test Spies or Stubs where appropriate, but it does mean that you don't need to jump directly into mocking which can lead to fragile tests.
If you do believe in mockist style testing, defining collaborations and going from there, then the high level BDD tests are a good place to do it however because thats the place where you will be thinking of high level interactions between entities/services/factories and so on. Showing those interactions in the tests could have some value, though whether you extract role interfaces is another issue.
Having said all this I do think you need to be thinking about/defining the GUI at the same time as working on the domain model to avoid overcomplication. For example you may implement a complex object hierarchy in the domain when for this version of the software something simple would have done. I've been bitten by this before, but I also think that starting from the GUI and working downwards is not the way to define a domain model. In my experience you usually need to do both GUI based work and domain work early on.
There are smart people who use outside-in testing in ways that I have no experience of (see this TDD thread which was a real eye opener for me, emphasizing just how differently people tackle testing/design).
High Level or All Levels?
For me the most exciting idea is writing high level BDD tests for two primary reasons:
- Stories - Lower level tests are less likely to be driven by stories from the stakeholder.
- Refactoring - High level tests are the ones that will provide benefits because they will be more immune to refactoring.
listStoryThis obviously isn't how you'd do it, but I'd be thinking that if you do use BDD at this low level then you are perhaps better just writing BDD tests without using something like NBehave (as shown on the wikipedia article of ListTest and by Jimmy Bogard in Converting tests to specs is a bad idea).
.IWant("my list to behave correctly when items are added")
.SoThat("I can use it in my software");
Can you use BDD for infrastructure/integration work?
NOTE: Here I'm talking about higher level (Scenarios, or Application Examples) specifications.
Ultimately everything you do is user driven but some problems make it difficult to tie your work back to a story.
For example my current project is an integration with an external system. This is quite a lot of work and defining user stories can be tricky as the users are not going to be interested till the integration is complete. Thanks to some brilliant help on the XP forum, not least Simon Jones' post, I've managed to get user stories to work for such a task but it does involve a little bit of work.
However for such a project do BDD tests make sense? Take the current piece of this project, a Windows Service that the users don't even directly use. I'm trying to use NBehave specifications but it can get a little odd, for example using the NBehave syntax who do I specify in the "As A" part of the story? Really the users don't even care that the service exists, but to be fair for this sort of work I'm happy to think outside the box a little and I think thats fine.
So yes I do think high level specifications can work for infrastructure/integration tasks.
Based On User Stories?
We use user stories and so the idea of writing the high level specifications based on user stories is attractive and I think it is a valid approach.
It is worth noting that whilst behaviour-driven.org seems to indicate that use cases are a good source whats-in-a-story does explain that its just as applicable where other requirements techniques are used (which is to be expected).
BDD and the Ubiquitous Language
I originally thought that BDD aimed to define, or help in defining, the (DDD) ubiquitous language. Its hard to know though so lets look at how BDD is linked to a ubiquitous language in some of the main articles:
- Wikipedia - "Behavior-driven developers use their native language in combination with the ubiquitous language of Domain Driven Design". I have no idea what this means, is it using the DDD ubiquitous language in the tests or are we saying that BDD is forming ubiquitous language for writing specificatons?
- Introducting BDD -Here BDD is the "ubiquitous language for the analysis process itself".
- Whats in a story -No mention.
- behaviour-driven.org - "It aims to help focus development on the delivery of prioritised, verifiable business value by providing a common vocabulary (also referred to as a UbiquitousLanguage) that spans the divide between Business and Technology.". This seems to indicate that your BDD specifications are supposed to look use the ubiquitous language.
As far as I can see there is absolutely no consistency in what the different sources of BDD mean when they talk about the ubiquitous language. I also think that taking the term ubiquitous language and using it outside of the context that DDD provides is unnecessarily confusing.
So what if the specifications are written in the ubiquitous language?
NOTE: This discussion only really applies to the higher level tests against your domain model, I don't think lower level (implementation detail) or infrastructure tests are going to be written in the ubiquitous language.
As discussed before according to behaviour-driven.org BDD:
...aims to help focus development on the delivery of prioritised, verifiable business value by providing a common vocabulary (also referred to as a UbiquitousLanguage) that spans the divide between Business and Technology."...This sounds good and if I'm writing the tests then I will use the ubiquitous language. However if I'm doing BDD properly then I'll have others involved:
- BDD Process - "A SubjectMatterExpert (typically a business user) works with a BusinessAnalyst to identify a business requirement"
- Whats in a story - "the stories are the result of conversations between the project stakeholders, business analysts, testers and developers. BDD is as much about the interactions between the various people in the project as it is about the outputs of the development process."
As discussed above my own view is that in many cases user stories will feed into the BDD specifications. So do I expect user stories to be written in the ubiquitous language, not really and for these reasons:
- Different Audiences - Our users are not necessarily our domain experts and even if some of them are we probably have some who are not. Having domain experts write the user stories is not good (been there, done that) and having the users define the domain model is no better (too simplified). I thus think that expecting the users to understand the ubiquitous language, which probably has little to do with their day to day job, is unreasonable.
- Clutter - Stories are there to specify the behavior the user wants. With this in mind I'm not sure that cluttering them with domain model details is any more useful than including GUI details in them. Does a user care what model you put in place, probably not and I'm not sure we should expect them to.
- Evolving Language - You are also likely to evolve your ubiquitous language as you learn more about the domain, probably resulting in it becoming more complex. The question would then be whether you build this complexity into the user stories, I'd argue that doing so will just confuse things.
Thats the way I see it for user stories and offhand I can't think why this wouldn't apply equally to BDD. So I'm not seeing BDD affecting our ubiquitous language all that much, I think instead when writing user stories we should aim to use the language of the users.
Obviously if your domain experts are involved in writing the BDD specifications then using the ubiquitous language will be more attractive.
So In Conclusion...
BDD is many things to many people and although some people are trying to tie it down I'm not sure it will work.
Unfortunately although I think it is positive that there are so many ways to describe BDD I do find that in some cases (ubiquitous language) it is unnecessarily confusing.