This week, Chris Matts tweeted, “Contemplating whether GIVEN-WHEN-THEN is back to front. The system should do <outcome> WHEN <event> PROVIDED <
stimulus context>… Hmmm.” Let’s try an example. “Given I have $500 in my account, when I withdraw $50 then I have $450 in my account” becomes “The system should show $450 in my account when I withdraw $50 provided I had $500 in my account before.” It doesn’t exactly roll off the tongue, does it? Putting the result first makes the sentence both more complex and more passive. Yet I can understand the impulse that triggered this tweet.
Given-When-Then describes the scenario in chronological order, which also makes it easier to automate. Often I don’t implement it in that order, though. Instead, I’ll flesh out the Then with code fixtures first, as the results are the primary focus. The When is usually a straightforward single interaction with the system. The Given describes the business pre-requisites, and these get translated into actions that make the When interaction work. Starting with the Given can lead us astray into specifying things that don’t need to be specified for this scenario.
Sometimes we discover that there are other pre-requisites, too. These may be things that are simply taken for granted or implied by the specified context of the test. We take for granted that the system is up and running. Having money in the account implies that the account has been opened. We also assume that there are no special cases in the context that would invalidate this scenario. The account having a hold put on the account by the fraud department is not a reasonable assumption. This is a case that needs checking, but in another scenario where the special context is explicitly mentioned.
If there are other things that need to be initialized for this test that are not mentioned in the Given setup, then it’s time to pause to reflect. Could this indicate a mismatch between the world envisioned by the business and the implementation in the system? That could be something to correct. Or might it be something that is often implicit in business conversation, but needs to be explicit in the test. Maybe the type of account affects whether or not a fee is applied to withdrawals. Sometimes the business gets into the habit of speaking in shorthand that leaves out some important distinctions.
I’m still happy with “Given <this context>, when <an interaction occurs> then <a result>” as a formula for acceptance tests or executable requirements. I don’t know that this is the only good formulation. I’m still looking for others that would naturally occur to business people, and would love to hear some examples if you have them. While I don’t think Do-When-Provided is natural business-speak (I could be wrong in some businesses), it’s good to consider alternatives.
Given-When-Then is a formula. While it can help stimulate our thoughts, it shouldn’t limit them.
In the same manner, Mike Cohn’s canonical expression of a User Story, “As a <type of user>, I want <some goal> so that <some reason>,” helps us to remember to think about which user and why they’re requesting this. I generally counsel teams not to actually write their stories in this way, as it often results in a wordy and repetitious list that obscures the essence of the story instead of highlighting it. There’s nothing like a long list of “As a customer, I want <to do something> so that I can make a purchase.” The formula can lull you to sleep. I’ve seen examples of this were “making a purchase” was not really what the customer wanted, it was the way what the customer wanted was implemented. And I’ve seen “As a user…” fill in for customer, obscuring the fact that not all users of the system are customers, and not all stakeholders who want something from the system are users.
These formulae are thinking tools. Use them in ways that provoke thinking. If they’re just chores to be done or checkboxes to be checked, they’re not helping.