DevOps Zone is brought to you in partnership with:

I have worked in software development since the mid 90's after a few years in the aerospace industry. Initially a database specialist always a programmer, currently with java. My focus is now on helping organisations to go faster with higher quality. Scrum and Agile are often part of that change. Martin is a DZone MVB and is not an employee of DZone and has posted 10 posts at DZone. View Full User Profile

Bad or Good? Behavior Driven Development within Scrum.

05.19.2010
| 7855 views |
  • submit to reddit

I wanted to explore the possibility of using JBehave to formalise scrums definition of done. The idea being to encapsulate a definition of done as a JBehave scenario. So in true scrum style I decided to timebox 4 hours of work dedicated to JBehave.

From a scrum point of view BDD can be used to turn the definition of done into a test artifact. The team produces scenarios for each task. With JBehave a scenario file describes the required behavior and test steps it will need to pass to be considered done. I.e Given some prerequisites, perform some action and expect some results. See the JBehave project for more detail as this is only a simple example.

BDD in 4 hours?

So scenarios are just text files describing the required functionality in terms of expected behavior. Even before development though, its possible to run them and see the pending expectations. Lets wizz though a simple example showing who in a scrum team is responsible for what. I already have a project that I use to explore test patterns so I thought I would just introduce it to that.  If you want the working version just take a fork from github.

Nb. I have a data fixture used in testing a complex page component. So whilst not a pure scenario I can make its existence part of the Givens. In this project, its likely that no real given is required, but a developer would add it during the build.

First the product owner and tester produce a simple scenario file describing behavior and expectations.

Given a data fixture
When a page is created with 20 items on a page
Then expected lines on a page is 4 with data items in a line 5

Next developers write a harness and flesh out the steps required to meet the behaviour.

We need to bootstrap the scenario and add steps to it. The general idea is to have a scenario test, that then includes the steps. This is one way of bootstrapping in the steps, other ways are available including a spring system that uses SpringStepsFactory. I ran into problems with the spring system as my project uses spring 3 and JBehave is still locked into spring 2.5.6. In addition I am using junit 4.8 and spring 2.5.6 requires 4.4. This is ultimately an issue as on many projects. I would not want to tie in those older versions. In fact other ideas in my project prevent me from doing this too. So in my timebox I avoid the issue and bootstrap manually.

The Bootstrap test class

public class SimplePageScenario extends JUnitScenario {
public SimplePageScenario() {
super(new MostUsefulConfiguration() {
@Override
public ScenarioDefiner forDefiningScenarios() {
return new ClasspathScenarioDefiner(
new UnderscoredCamelCaseResolver(".scn"),
new PatternScenarioParser());
}
});

addSteps(new SimplePageSteps());
}
}

Before adding the call to addSteps()) running the scenario shows the steps that are pending.

(org/testpatterns/scenarios/example_scenario.scn)
Scenario:
Given a spring data fixture (PENDING)
When a page is created with 20 items on a page (PENDING)
Then expected lines on a page is 4 with data items in a line 5 (PENDING)

Finally the developers fill in the Steps class adding sections that match against the scenario keywords, Given, When and Then. Development is done until the behavior passes the test.

public class SimplePageSteps extends Steps {

private SimplePage page;

private final PageDataFixture dataFixture = new PageDataFixture();

@Given("a data fixture")
public void givenASpringDataFixture() {
notNull(dataFixture);
}

@When("a page is created with $itemsOnAPage items on a page")
public void createPage(int itemsOnAPage) {
page = SimplePage.newInstance(dataFixture.getDataItem(), itemsOnAPage);
}

@Then("expected lines on a page is $linesOnAPage with data items in a line $itemsInALine")
public void validatePage(int linesOnAPage, int itemsInALine) {
Map expectedLines = dataFixture.createPageExpectation(linesOnAPage, itemsInALine);

Map actualMap = page.getMap();

ensureThat(actualMap, is(expectedLines));
}

}

Good Points

  • I like the potential to get key scrum members interacting. The collaboration between the testers and product owner is an important one as it should flesh out questions about behaviour at an early stage. Similar benefits occur when the development team starts to get to grip with the behavior.
  • Having a simple scenario artifact means the product owner can get involved with something that actually becomes part of the continuous integration.


Bad Points

  • The bootstrap is clumsy. Having to add steps means that after producing the new scenarios development have to get involved before the pending steps appear. There are other ways to bootstrap. The spring system is a step in the right direction, in fact I would like to use injection throughout the application. This still does not solve the problem of having to edit something before the steps appear. I would prefer that once the scenario is in place, steps are automatically found as they are written, and appear as not started until they are cut.
  • Extending Junit Testcase is also a problem. Its highly likely that in more complex projects we would need mocking techniques or spring based tests. These have their own runners brought in with the @RunWith annotation. It would be better if there were some way to bootstrap the behaviour into any other test framework.
  • In my 4 hour timebox I did not get the reporting working. Unfortunately the reporting requires more coding, and setup and is far from being just a bit of maven configuration.
  • When running from maven things did not work until I configured the maven-resource-plugin to copy over the scenario files. This should have just worked out of the box.
  • Most of my 4 hours was taken up with configuration which was compounded by the slim documentation.


Conclusion

Attempting a behavior driven approach using scenarios is worth doing. I could see the benefits. Not sure if JBehave is the solution for me though. Difficult to configure, and incompatibilities with other frameworks would put me off at the moment. I will find some time to have a look at easyb another java BDD system next.


References
Published at DZone with permission of Martin Harris, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Jilles Van Gurp replied on Wed, 2010/05/19 - 12:56pm

One of the teams at work recently demoed this. They went to quite a bit of trouble to get this going as well (hooking it up to maven, getting the reporting done properly, etc). They've been using this for a few sprints now and it is working well for them.

However, I'm not convinced I need it. Basically all JBehave does is enforce a pattern of setting up your test fixtures (@Given) exercising your code (@When) and running some assertions (@Then). That's nice but sort of what I expect to find in any decent test.

The real deal is coming up with reusable steps that will make it easy for you to write new tests in a semi declarative way. For that I've been developing a little framework using just HttpClient with which I can easily excercise our REST APIs. It uses the builder pattern to construct requests and then a similar pattern for asserting stuff on the response.

So for the 'Given' type steps I have Helper.ensureFooExists(Foo foo) type static methods. Then to deal with the when and then part I have calls like Helper.post().withbody(...).withHeader(...).sign().execute().assertStatus(201).assertResponseContains("/foo"); 

This DSL like approach makes for really easy to read and write tests and assert things on the response. The tests are blackbox tests so it is easy to practice TDD (or BDD if you insist, or contract driven development). With enough logging, you can use them as acceptance tests as well.

 

Martin Harris replied on Wed, 2010/05/19 - 4:22pm in response to: Jilles Van Gurp

Yes, I tend to agree.  Where I see the real benefit is in improving the interaction between product owner, tester and developer.  A way to have an artifact that is started by the product owner, fleshed out by the tester (possibly even down to writing some of the test) and aided or finished off by the developer.

 In one way JBehave is good because the artifact that the Product owner sees does not contain code.

 I will find some time to look at Tumbler (http://code.google.com/p/tumbler-glass/) and easyb (http://www.easyb.org/).  Tumbler looks like it has great pedigree.

 The environment I work in is often Flex or Silverlite front end.  Even so, acceptance of some of it against the XML interface using a system like the one you mention, with a similar fluid interface could be useful.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.