Why specification by example?
I recently attended the Agile Testing and BDD Exchange. It was great to get my head back in to that space again and listen to some really knowledgeable speakers. We even got a Gojko versus Dan North impromptu sparring session, and you couldn’t ask for two better speakers to be bouncing ideas off each other, and a fair amount of insightful stuff came out of that.
As ever with such conferences, it got the whole subject rattling around my head again – it’s always been one of those areas I’ve instinctively felt is getting it right, in terms of promoting collaborative specification by example involving different viewpoints to perform as much debugging of requirements as possible ahead of writing any code.
The key benefit I have always seen in agile is to reduce risk by providing a rapid and iterative cycle of design, build and test. By test I don’t just mean testers testing or verifying that scenarios have passed – I mean also the whole group testing its assumptions by reviewing what they built, and using the experience it gives them to validate the assumptions they had about what they wanted before they started that build iteration.
In other words, are we building the right thing? Has our view changed of what the right thing is? It normally does as we gain experience.
For me, specification by example extends the reach of this model further back in to the delivery cycle, which can only serve to further help us to build the right thing. As we decide what we’re going to build, we ideally need three points of view in the room:
- The proposer (apologies for making up a new word) – that is, someone who has something they want to build, and who proposes the requirements;
- The builder – that is, someone with repeated experience of the ambiguities inherent in expressed requirements, and resolving those ambiguities to produce executable software;
- The breaker – that is, someone used to taking requirements and built software, and spotting the ‘unhappy paths’ which could cause that software to malfunction or work in a way other than that intended by the proposer and the builder.
The proposer working on their own is very dangerous, as most requirements are too complex to be understood by a single person without the back and forth of conversation to elaborate them. This normally results in wordy documents that only expound the complexity of some of the problem space, rather than reducing that complexity to effective and appropriate solutions that can be built.
The proposer only working with a builder is usually pretty dangerous too, as the builder naturally tends towards being satisfied once they have spotted a happy path to a working piece of software. They tend not to be interested in the unhappy path. (I speak as a builder, so if I’m maligning anyone out there my apologies – it’s a tendency I’ve spotted in myself).
By getting all three mentalities in to the room in the requirements stage, we can iterate rapidly around the requirements, applying a level of agile require -> build -> break activity, before committing ourselves to a build cycle which is building the wrong thing. You’ll never catch all of it – all design is effectively a thought experiment, and some of the ambiguities will just be impossible to spot until you’ve been through a build iteration.
But by specifying collaboratively, using simple tabular examples wherever possible, we maximise the value and precision of that design phase, and give ourselves a better chance to build the right thing than any other technique I see around at the moment.