I think the following is a problem which falls firmly between two stools, so please forgive me if this is the wrong place, but I think it's more of a linguistic question than a computer question.

Gherkin is a natural language specification of what a computer system should do. It is intended to read properly for English speakers, and it looks something like this:

Scenario: A user without permission may not contact another user.
  Given a user called Robin
  Given a user called Jack
  Given Robin has no permission to talk to Jack
   When Robin tries to contact Jack
   Then Robin will see an error message

The phrases that appear after 'Given', 'When', or 'Then' are chosen by whoever's implementing the system, and become stock phrases for use in many different scenarios, but each must always appear after an initial 'Given', 'When', or 'Then'.

The 'Given' 'When' or 'Then' do not form part of the phrase-action definition; in fact, they can all be replaced by 'And' or 'But' to semantically repeat the previous line's initial word, but I don't think that changes things in terms of the answers I'd be after here.

The problem is this: because the workings behind the Gherkin code do not distinguish between 'Given', 'When', or 'Then' there is ambiguity in some of the lines above if you change the first word.

Given Robin has no permission to talk to Jack
 When Robin has no permission to talk to Jack
 Then Robin has no permission to talk to Jack
  • The 'Given' line would be understood to be telling the computer to set the system we're trying to test up in such a way that Robin has no permission to talk to Jack.

  • The 'When' line could be understood to tell the computer to wait until some operation has made it so that Robin has no permission to talk to Jack.

  • The 'Then' line would be understood to be asking the computer to check that - right now - Robin has no permission to talk to Jack, and to fail the test if that isn't so.

...but we can only implement one of those three, and then we have the two remaining phrases which won't do what they look like they should be doing, were someone to accidentally write them with the wrong leading word.

Even if the system did take the first word into account, having a test that repeated the same phrase for the different leading word would be confusing - especially since we use the 'And' or 'But' words so tests read more pleasingly.

The question is: is there a useful way to choose the phrase so the Given, When, and Then senses cannot clash? Ideally, it would be a cookie-cutter sort of solution, because the people writing these scripts aren't necessarily native speakers.

For instance: in the example, it's fine to have

Given no permission for Robin to talk to Jack

because you can't substitute 'When' or 'Then' for 'Given'.

It's also fine to have

Then Robin will see an error message

because substituting 'Given' or 'When' for these would read strangely in context (particularly if we get into the habit of 'Given' only taking a noun-phrase like 'a user called Robin').

One solution would be that:

  • Given always has a past tense,
  • When has a present tense, and
  • Then has a future tense.

... but that's a bit nuanced, particularly for people whose native languages don't have those sorts of tense.

Another would be that

  • Given only takes noun-phrases, possibly with qualifiers like 'which' or 'who',
  • Then is always followed by 'verify', and
  • When just has a present tense SVO,

... but that leaves all 'When' phrases able to fit with both 'Given' and 'Then'.

Is there a good way to write these phrases so they read badly if preceded with the wrong one of 'Given' or 'When' or 'Then'?

Disambiguation: 'Given' 'When' and 'Then' are not considered distinct (as I myself originally expected): by way of hastily crafted example:

Given(/^I authenticate as the original user$/) do

is exercised by any of

Given I authenticate as the original user
When  I authenticate as the original user
Then  I authenticate as the original user

But conventionally, 'Then' clauses should not do things, so this last should be as follows:

Then(/^verify I am authenticated as the original user$/) do
  unless (device.navigate_to('Profile').get_user == 'Jane')
    fail "Wrong user found!"

Then verify I am authenticated as the original user

That definition would also be exercised by these unnatural versions, but hopefully no English speaker (native or otherwise) would write or accept:

Given verify I am authenticated as the original user
When  verify I am authenticated as the original user

(If we were testing the password reset system, I imagine we could have 'Then verify I CAN authenticate as the original user' navigating to login, trying to authenticate with the new password, and then navigating to the profile to check the current user.)

In fact, we have many steps defined as 'And(/.../)' for no earthly reason I can think of. Some implementations of Cucumber might care about the Gherkin verb, but the Ruby version we use certainly doesn't.

'Given' 'When' and 'Then' can even be replaced by '*' - perhaps so implementations can explicitly require the 'Given' 'When' or 'Then' at the start of the phrase - but then you have a potential clash if you want to use 'And' or 'But' with two otherwise identical phrases.

We actually use the '*' form for our 'tests' which walk through the application taking screenshots for our design team, product managers, and translators to see how those screens look in other languages:

Scenario Outline: Gallery Upload
* I launch the app in <locale>
* I do some navigation and screenshot stuff here
  • Surely then must behave differently as you need a clause to evaluate to give an error or not. This is a computer answer suggesting that you don't have the correct information
    – mmmmmm
    Aug 27, 2020 at 13:49
  • I take issue with your ambiguities in Given/When/Then. Given sets up the system (as you say); but when can function like if — it doesn't have to mean "wait until". And then surely can't require a verification to take place because it is unequivocally a result. I am surprised that "the workings behind the Gherkin code do not distinguish between 'Given', 'When', or 'Then'," because that means that those tokens aren't actually required at all and you could simply have a word like "token" (which is meaningless and can't direct logic flow). I guess this comment is a frame challenge.
    – Andrew Leach
    Aug 27, 2020 at 14:38
  • On the other hand, perhaps I've misunderstood and it's because the tokens are meaningless that you're asking about how to imbue meaning by the structure of the clause which follows.
    – Andrew Leach
    Aug 27, 2020 at 14:41
  • Surely 'Then statements always starts with Verify' leads to an infinite loop of 'what if the user puts the wrong thing after 'verify'' ? conversely, if you are happy with that as a solution, what's wrong with "Given statements always start with 'Given'"?
    – JeffUK
    Aug 27, 2020 at 15:09
  • @mmmmmm Given/When/Then do not behave differently: I can define a clause with Given(/I do something/) but use it with When I do something. Sep 7, 2020 at 15:24


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.