samedi 22 novembre 2014

About BDD pt 2

I began this series of blog posts on Behaviour Driven Development practice with an introduction about the principles. This one is going to deal with practice and tools. BDD seems to be an interesting topic for tool developers, as transforming specifications to code could be, and the amount of available pieces of software is impressive.

Two approaches can be found to implement BDD: integrate spec elements directly in code or translating features written in plain text to test steps. The first one is represented by tools like Rspec, Jasmine or Spock. Tests are directly coded and executed. Specs fragment are written in it and displayed as output during execution. It's the kind of tools I know the most and they allow to write really readable tests. They are fast enough use them for TDD.

The second approach is represented by tools like Jbehave, Cucumber, SpecSlow and Behave, Lettuce and Pytest-BDD for python. With them, you write your tests in plain text files using Gherkin language (given - when - then, etc.). The tool kit initializes your test steps from the text files which prevents you to write boiler plates code and parsing regexes. All you have to do is to fill your test steps to make them call your code and begin the red-green-refactor work flow.

So you can choose your approach and begin to have fun with BDD. You may wonder:

But what do you call? If the specs are written by business users, my test code should exercise the system directly from the UI, right?

You might think that especially if you want to link your test scenarios to your backlog items. But the tools are not prescriptive about that. If you look at Jbehave homepage, the examples do not mention UI elements nor actions. Actually, basing your test strategy mainly on UI test is a bad practice (see the ice cream cone of tests). If you are to use BDD for your specification process, it means that your spec should avoid to describe the system through the UI. To me that's the revolution: it forces us and our users to specify by example and separate whole system and UI behaviour. You can then specify your UI and make it interact with mocks in tests. You gain time since UI tests are hard to write and execute. You gain time because you can reduce the number of end to end system tests, making your whole suite execute faster. These practices of decoupling and separating system layers exist for decades in software de development. Your job here is to change business users mindset and find a specific (ubiquitous?) language to specify and exercise your system. Yeah, human interaction. Damn.

BDD tools are pretty cool and BDD principle of building a common runnable specification document between developers and end users is laudable. You have to choose an approach whether you want direct test coding (Rspec) or use Gherkin. The former forces the developers to write the specs, the latter provides more freedom for business people to write the test as long as they conform to the given-when-then pattern.

The problem with the latter is that it is often presented in a worng way. I've seen two talks about Cucumber and Behave and the example was the same: testing a web authentication form. I admit it's seductive since you have this kind of thing in almost every app and it exposes a different behaviour if the user passes or fails the authentication challenge. My reproaches:

  • Don't present a system test form the UI! It's a bad practice!
  • Who cares? That's a feature provided by all decent web frameworks! That's not why BDD has been thought for!

Today I stick with classical xUnit framemork. I pay attention to the way I write the tests methods in order that the test report may be understandable by everyone. My method names look like:

the_system_does_something_when_foobar_is_entered()

However, I think I'll try BDD + Gherkin sooner or later and I'm motivated to promote the approach to clients.