Thursday, 2 September 2010

Refactoring Given/When/Then

I've come to the view that Given/When/Then is a poor way to think about scenarios, and is even worse for writing them. It makes me turn even the simplest situations into a ramble. And I don't think it's just me.

Given a user called Fred
And user Fred is logged in
And user Fred has an empty shopping basket
When Fred adds a $15 screw-driver
And Fred adds a $12 lamp
And Fred adds a $12 lamp
Then the total of Fred's bill is $39

If I start with Given/When/Then, I end up having to go through a laborious process of simplifying, getting rid of unnecessary details. In our example, above, Fred may be needed behind the scenes but doesn't add anything useful to the description.

Given we are logged in
And we have an empty shopping basket
When we add a $15 screw-driver
And add a $12 lamp
And add a $12 lamp
Then the total bill is $39

Do we need that bit about being logged in? No. Readers will likely assume it and, even if they don't, who cares anyway? It's irrelevant to what I'm trying to explain.

My rule of thumb is: if the context is unexpected (e.g. we're trying to explain what happens when you aren't logged in) then we need to mention it, but if the context can be inferred from the other parts of the scenario, or from common sense, then leave it out. There's a feeling that adding context will remove ambiguity, but all it actually does is complicate the example.

Given we have an empty shopping basket
When we add a $15 screw-driver
And add a $12 lamp
And add a $12 lamp
Then the total bill is $39

Are the words "screw-driver" and "lamp" necessary? I think they are. If we removed those words and just had the prices, the example would be harder to understand. You need something to show that the prices represent items. Using more abstract labels (e.g. "item A", "item B") is a possibility, but doesn't seem to buy us much.

What about the "empty shopping basket"? Can that be reasonably assumed? Yes, but rather than starting with an empty shopping basket, how about starting with a full one and dropping the "when" part?

Given a basket containing a $15 screw-driver
And a $12 lamp
And a $12 lamp
Then the total bill is $39

Finally let's remove the duplication.

Given a basket containing a $15 screw-driver
And 2 x $12 lamp
Then the total bill is $39

OK, this doesn't suck as much as what I started with.

But why not just write this:

1 x $15 screw-driver
2 x $12 lamp

Total bill = $39

This is what I might write on the back of an envelope if I were giving an example to somebody. With the right tools (e.g. Concordion), I can code it up exactly as I just wrote it. I don't need to use Given/When/Then. I used to think it was a good way to structure the example, but I've changed my mind.