Executable Documentation - EasyB style
Posted by Ken Brooks Mon, 04 Feb 2008 21:45:00 GMT
One of the challenges of maintaining and enhancing an existing system is that the documentation goes out of date probably before you even finish it the first time. Whenever someone has a question for me about how does something work I usually refer to the location of truth. That would be the code itself, which is always the most up to date source of documentation. So the closer to the source you get the better chance your documentation has of standing the test of time.
Unit Tests helps in this area in that they can outline the assertions we are placing on our code. That too must stay up to date because it is also close to the code. Unfortunately unit tests are often more complex than the code they are testing and ultimately end up not being very good sources of documentation either.
There has to be a way to build human (possibly even business person) consumable documentation that stays in sync with the truth.
Enter EasyB.
EasyB is a BDD testing framework written in groovy and java. It provides what we like to call executable documentation. This is achieved by taking TDD, all sopping wet with techy mess, and throwing it in the evolutionary dryer with a nice fabric softener. Out from the other end pops a nice fluffy testing framework that can not only provide up-to date documentation about the application every time it is built, but can even bridge the gap between business requirements and developer interpretation.
It has two supported ways to write specifications. Behaviors and Stories. Its just a matter of personal taste on which you use for each component in your project. Behaviors often are shorter and good for utilities. Stories are more verbose and usually map to a series of interactions.
Behaviors look like this:
it "should return null for null input to trim", {
ensure(StringUtilPartial.trim(null)) {
isNull
}
}
it "should return the string without whitespace at either the end", {
StringUtilPartial.trim(" somestring ").shouldNotBe null
StringUtilPartial.trim(" somestring ").shouldBe "somestring"
}
Stories look like this:
scenario "appending string to empty string buffer", {
given "an empty string buffer", {
stringBuffer = new StringBuffer()
}
when "a string is appended", {
stringBuffer.append("somestring")
}
then "the buffer should contain the string appended", {
stringBuffer.toString().shouldBe "somestring"
}
}
scenario "appending string to existing string buffer with existing data", {
given "a string buffer with an initial value", {
stringBuffer = new StringBuffer("abcd")
originalStringBufferValue = stringBuffer.toString()
}
when "a string is appended", {
stringBuffer.append("somestring")
}
then "the buffer should contain the original value plus the appended value", {
stringBuffer.toString().shouldBe(originalStringBufferValue + "somestring")
}
}
What you have just witnessed is that we have tested our code and written documentation at the same time. That documentation will evolve right along with the code its testing and nobody has to be the low man on the totem pole and write documentation.
All well and good, but what we wrote above still wouldn’t be what a business person would consider documentation. Too much techy goobledeegook in there. Easyb has another trick up its sleeve especially when dealing with the story based specifications. When I ran the story above a report is generated and here is what the contents look like:
Story: string buffer
scenario appending string to empty string buffer
given an empty string buffer
when a string is appended
then the buffer should contain the string appended
scenario appending string to existing string buffer with existing data
given a string buffer with an initial value
when a string is appended
then the buffer should contain the original value plus the appended value
What?! Where did that english documentation come from? Shhh.. don’t tell your developers that they wrote it.
Check out easyb at easyb.org and join the group to keep up on the latest developments. The current release of easyb is 0.6 and some of the syntax presented above (shouldBe for example) is in the trunk and not a release yet.
