Monday, November 07, 2005

Behavior Driven Development

I recently read an interesting paper by Dave Astels, entitled A New Look at Test-Driven Development, which suggested that Test Driven Design is overly focused on testing, which gets in the way of reaping the true benefits of TDD.

I agree that using the word “test” when describing TDD definitely gets in the way, when explaining it to other people.  Management asks, “Why are we hiring testers if developers will be writing tests?”  Developers ask, “Why should I write unit tests for code that will get tested by the (manual or automatic) acceptance tests?”  And so on.  You get the usual objections to TDD.

So I am down with giving TDD another name, but what threw me was the suggestion that we ought not to use the word “test” when actually writing the tests.

In Behavior Driven Development, tests are called “specifications.”  Fixtures are called “contexts.”  And instead of assert, one would say “should.”  (Dave’s essay has examples of their usage.)

Initially, I was fairly dismissive of what seemed like a cosmetic change, but I decided to give it a go for the past week.  Here is what I found.

I wrote more, smaller test fixtures.  Whereas I used to write test fixtures with names, like CustomerFixture, I found myself creating many little contexts, with names like CustomerWithOverdueBill or CustomerWithoutAddress.  

I wrote more asserts per test.  Each test started with a particular context, invoked a particular operation in that context, and then verified the expected resulting context.  That verification often took multiple asserts.

The tests naturally had better names.  In the past, when writing tests for a Customer class, I might have tests with names like testSetAddress.  Now, I find myself thinking in terms of scenarios, so that the CustomerWithoutAddress context might have a specification like settingAddressForFirstTimeSendsNotifcation.

In summary, this change in perspective has proven extremely useful, so I am sticking with it.