BDD

Remember what it felt like the first time you rode a bicycle completely on your own? After a lot of practicing and falling down you did it. Finally the freedom! From that moment on it only went better and better. After a while it even becomes a second nature and you cannot even imagine how it is not being able to do it.

This experience is exactly what I had while learning Behaviour Driven Development (BDD). After years of experience in web development and having tried so many different ways of working it dawned on me that BDD is different.

The beginnings

The first time I saw a feature file it wasn’t love at first sight. Yet another agile “DD” thing and most likely it will ad additional steps in the workflow. Not that I minded that if it helps the project, but soon it became clear that I misunderstood BDD. The most common mistake people make is that they think it is about testing and is a big brother of TDD.

This is something that I have always loved about my profession. Getting requirements from stakeholders and moulding them in usable software. The problem with how I worked (and a lot of people still do) is two things namely tests and documentation. A lot of developer really love coding new stuff or completely refactor the old. Being focussed on solving a complex problem with a nice design pattern for example does give a kick.

Business value

Having said that is safe to say that no customer/manager/stakeholder cares about your fancy strategy pattern nor the awesome new framework you used. From the outside in it isn’t even visible most of the time. They care about the desired functionality and if it brings the business value as they hope it will.

In the interactions between the various people that Dan is talking about it is very important that they understand each other. This is exactly where my love for BDD began to grow. “Give me an example of what you just said” and then the examples brought so much more insights then i expected. Who would of guessed that a simple question like that could be a complete game changer and finally really understand the problems the domain expert is dealing that.

Now we can actually focus on what brings value together. However talking about sinon.js and websockets should be done with your tech buddies 😉

Awareness

Since doing more and more BDD in my projects and as a second nature asking more questions it is becoming clear to me that non-technical people are completely unaware of solutions for their basic problems. They find their way around it. I find myself asking: “Are you really copy pasting that every day for an hour?”. It really makes me aware of what should be build.

On the flip side when explaining the feature files and running the executable specifications that came out of it often brings awareness to the stakeholder that their requests have a bigger impact on development than they thought.

Conclusion

Riding a bicycle is something you will always know how to do once your learned it. The same goes for learning BDD and I encourage you to take the path of learning it. It is hard to fully grasp I must admit, but very much worth it.

Although it’s documented on https://github.com/cucumber/cucumber-js it wasn’t clear to me what the best is to deal with callbacks in step definitions. After working with cucumber-js for a while it is now clear. So let me share my experiences with you in this area.

When you run it for the first time and have not implemented any of the steps you will get the following snippits:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

this.Given(/^there isadefaultcallback$/,function(callback){

// Write code here that turns the phrase above into concrete actions

callback.pending();

});

this.When(/^the promise has been made$/,function(callback){

// Write code here that turns the phrase above into concrete actions

callback.pending();

});

this.Then(/^something isasserted$/,function(callback){

// Write code here that turns the phrase above into concrete actions

callback.pending();

});

As you can see the default behavior is a callback. So it is easy to implement the Give to set up the stage.

1

2

3

4

this.Given(/^there isadefaultcallback$/,function(callback){

api.addFilter('title','something');

callback();

});

Now usually the When step involves some kind of back-end call and promises are a common way to handle this.
The great thing is that we can you return a promise as-is, but the catch here is to remove the callback from the arguments. There is some magic going on there and if you leave it in you won’t go to the next step and the whole process will keep hanging. I found myself using console.log quite a few times.

JavaScript

1

2

3

this.When(/^the promise has been made$/,function(){

returnapi.myPromise();

});

In the Then step we assert the outcome the promise by getting the state (for example). Also here we don’t need the callback, because if our assertion fails it will throw an error and your scenario failed. Otherwise it can carry on silently like the documentation indicates.

JavaScript

1

2

3

this.Then(/^something isasserted$/,function(){

api.getState().title.should.equal('something');

});

Now to be honest this made the experience of using cucumber-js a lot better. It is a very good tool to have in my daily work and hope this article will help you in that area as well.

One last thing… All of the above can also be achieved with only callbacks, however this makes the step definitions a whole lot messy-er and that’s bad when your projects grows bigger.