Executable documentation the easy way
Behavior Driven Development, or BDD, elegantly shifts ones focus from tests to behavior and in doing so, opens up a whole new set of possibilities when it comes to collaboration and indeed, verification. In fact, by focusing on behavior (in terms of thinking about what something should do and how one could ensure things happened as planned), I’ve found that BDD effectively drives development in a rapid manner– what’s more, through the notion of stories, BDD can bridge the stakeholder-developer gap that often exists. As such, behaviors turn out to be phenomenal documentation– documentation that is living and can be executed often.
Having seen the light with RSpec and indeed, rbehave, I found myself wanting the same simple expressiveness in Java– accordingly, I began experimenting with Groovy and internal DSLs (with the help of some friends) and came up with something I find quite simple and expressive.
The first incarnation of behaviors has a simple feel and attempts to read in plain English in an effort to have stakeholders participate. In fact, the simple language is like so:
before "some description", {
//do fixture like logic
}
it "should do something...", {
}
//as many its as you'd like
For instance, taking the same behavior I coded in an earlier post, I now have:
before "initialize zipcodevalidator instance", {
zipvalidate = new ZipCodeValidator()
}
it "should deny invalid zip codes", {
["221o1", "2210", "22010-121o"].each{ zip ->
ensureThat(zipvalidate.validate(zip), eq(false))
}
}
it "should accept valid zip codes", {
["22101", "22100", "22010-1210"].each{ zip ->
ensureThat(zipvalidate.validate(zip), eq(true))
}
}
As I tried to incorporate this first incarnation into an existing legacy project, I found that I needed a higher level story line– for instance, I wanted to ensure the behavior of a DAO style object worked accordingly; however, in order to do so, I needed a seeded database and a Spring initialized context.
As a result, I began to realize that the simple before-it style of behaviors wasn’t enough– indeed, following JBehave’s story style of development, I ended up adopting a given-when-then language. For instance, a simple story (or scenario, really) looks like this:
given "some needed precondition", {
}
when "something occurs", {
}
then "ensure that something else is true, etc", {
}
This DSL supports multiple givens, whens, and thens as well– the given closure delegates to an object that can handle database seeding via DbUnit as well.
For instance, if you need to put a database into a known state before a story, you can do any one of three options, using the database_model call:
given "the database is properly seeded", {
database_model("org.hsqldb.jdbcDriver",
"jdbc:hsqldb:hsql://127.0.0.1", "sa", ""){
def writer = new StringWriter();
def builder = new MarkupBuilder(writer);
builder.dataset(){
word(word_id:1, spelling:"bellicose", part_of_speech:"Adjective")
definition(definition_id:10, definition:"demonstrating willingness and willingness to fight",
word_id:1, example_sentence:"The pugnacious youth had no friends left to pick on." )
synonym(synonym_id:20, word_id:1, spelling:"belligerent")
synonym(synonym_id:21, word_id:1, spelling:"aggressive")
}
return writer.toString()
}
}
In the above code, a MarkupBuilder is used to create an XML representation of the data desired in a database– note that the closure returns a String– this is key as it means there are multiple ways to return XML to the delegate, which ultimately uses DbUnit’s native data types to seed the database.
given "the database is properly seeded", {
database_model("org.hsqldb.jdbcDriver",
"jdbc:hsqldb:hsql://127.0.0.1", "sa", ""){
"""<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<word WORD_ID="1" SPELLING="pugnacious" PART_OF_SPEECH="Adjective"/>
<definition DEFINITION_ID="10" DEFINITION="Combative in nature; belligerent."
WORD_ID="1"
EXAMPLE_SENTENCE="The pugnacious youth had no friends left to pick on."/>
<synonym SYNONYM_ID="20" WORD_ID="1" SPELLING="belligerent"/>
<synonym SYNONYM_ID="21" WORD_ID="1" SPELLING="aggressive"/>
</dataset>
"""
}
}
In the code above, a String representation of the XML is returned as is– this is probably the least desired mechanism to do this; however, it works.
Lastly, the delegate can be fed a String representation of an existing DbUnit XML document from the file system as follows:
given "the database is properly seeded", {
database_model("org.hsqldb.jdbcDriver",
"jdbc:hsqldb:hsql://127.0.0.1", "sa", ""){
return new File("./src/conf/seed.xml").text
}
}
Putting it all together yields stories that are readable by stakeholders and are quite effective as documentation– executable documentation:
import org.springframework.context.support.ClassPathXmlApplicationContext
given "the database is properly seeded", {
database_model("org.hsqldb.jdbcDriver",
"jdbc:hsqldb:hsql://127.0.0.1", "sa", ""){
return new File("./src/conf/seed.xml").text
}
}
given "the DAO instance has been obtained from Spring", {
context =
new ClassPathXmlApplicationContext("spring-config.xml")
dao = context.getBean("widgetDAO")
}
when "findWidget is called with a valid id", {
wdgt = dao.findWidget("34-02w")
}
then "a working Widget object should be returned", {
ensureThat(wdgt, isNotNull())
ensureThat(wdgt.getLineItems().size(), eq(2))
}
Running this story is as easy as invoking the Ant task- for instance, in Gant, the task looks like so:
Ant.specrunner(){
report(location:"${defaultdir}/task-report.xml")
behaviors(){
fileset(dir:gbehaviordir){
include(name:"**/*Story.groovy")
include(name:"**/*Specification.groovy")
}
}
}
As you can imagine, using normal Ant is similar (except with a lot of XML)–
<specificationrunner>
<report location="${loc}/report.xml"/>
<behaviors>
<fileset dir="${loc}" include="**/*.groovy"/>
<behaviors>
<specificationrunner>
The story and behavior framework is built upon JBehave, so anything you can do in JBehave, you can do in various closures– notice the ensureThat methods– all matchers are available as well.
Executable documentation is a sure fire way to:
- accelerate delivery
- quantify development
It bridges stakeholders and development and effectively builds confidence that development is building the right thing. Using a DSL, like the one above, makes this process easier as well.

November 13th, 2007 at 11:43 am
[…] One thing these copasetic frameworks have in common is a DSL that attempts to make the act of verification (either through tests like Fit or through specifications via RSpec, etc) easy. Accordingly, over the last few weeks, I’ve been playing around with a Groovy based framework (targeting Java developers) that attempts to mimic aspects of RSpec and JBehave’s story framework. […]
February 4th, 2008 at 8:40 pm
[…] Stories offer a powerful mechanism for conveying information– indeed, if written correctly and combined with an adequate means of validation, stories can become executable documentation. For instance, easyb (a behavior driven development framework for the Java platform) supports a story format that consists of: […]
July 14th, 2008 at 12:07 pm
[…] The notion of executable documentation, where a stakeholder’s language is leveraged as a means for decreasing the impedance mismatch between what they want and what they ultimately receive, has, for some time, been ambition of many a development team (and corresponding stakeholders!). While executable documentation proves to be an effective means in assuring customers get what they actually want, this technique also proves to facilitate a deeper level of collaboration between all parties because everyone is using the same language. […]