[Gherkin] What's the preferred way to reuse/restate "Given" conditions across multiple scenarios?

184 views
Skip to first unread message

Justin Holzer

unread,
Mar 17, 2014, 11:57:35 PM3/17/14
to cu...@googlegroups.com
I am just getting started out with writing specs using Gherkin. I think it's great, but there is one case in particular where I am unsure of what the best practice is, and was hoping you all (the wonderful Cucumber community), could lend some advice.

I have a feature in which most, but not all, of the scenarios are dependent on the following "Given" conditions:
  • The user must be authenticated
  • The feature must be enabled for the group that the user belongs to
  • The user must also be granted explicit permissions to access the feature
I have created scenarios to provide examples of what should happen in the cases where each one of the above conditions is not met...

Scenario: The user cannot access feature X because they are not authenticated
 
Given that the user is not authenticated
 
When they attempt to access feature X
 
Then they receive an unauthorized error

Scenario: The user cannot access feature X because it is disabled for their group
 
Given that the user is authenticated
 
And feature X is disabled for their group
 
When they attempt to access feature X
 
Then they receive an unauthorized error

Scenario: The user cannot access feature X because they are not granted permission to access it
 
Given that the user is authenticated
 
And feature X is enabled for their group
 
And the user is not granted permission to access feature X
 
When they attempt to access feature X
 
Then the receive an unauthorized notification

The first scenario above will be the only scenario in which the user is not authenticated/signed in. Is it truly necessary to reiterate that the user is authenticated in every other scenario? Can the fact that the user is authenticated safely be assumed in all scenarios other than the first? If not, is there a better way to indicate that it applies to all scenarios, except for one, without explicitly repeating it again and again?

It also feels like the way that I have written the above scenarios is implying the order in which the conditions should be checked, which is not what I want to imply at all. These are high level requirements after all, not technical design documents.

Similarly, for all scenarios other than the 3 mentioned above, it will be a "Given" that the user is authenticated, they have the feature enabled for their group, and they have permission to access it. Again, will it really be necessary to repeat these facts for every scenario (other than the 3 mentioned above)?

I feel like I'm missing something, as I'm sure others have encountered cases similar to mine. Is there a better/DRY-er way to write scenarios like the ones I describe? Any suggestions would be greatly appreciated!

Regards,

Justin

Roberto Lo Giacco

unread,
Mar 18, 2014, 5:01:21 AM3/18/14
to cu...@googlegroups.com
Syntactically speaking you have the Background section you can use to move the Given authenticated into, then use a different Given condition for the non authenticated step.

I'm not sure I would use that characteristic of the language in this context though, you have to evaluate how much important is the fact the user is authenticated in the context of your feature. I understand you are describing an authentication and authorization subsystem, what about splitting up the authentication stage from the authorization stage? If you authenticate in a feature you would deal with the auth / non auth in one file where the provided credentials are relevant (I usually tend to have password change and password forget scenarios in there, including password rules). In a different file you can describe the authorization features and you can have functions/operations and groups in there and you can move the authentication step in the Background section as it is no more highly relevant to what you are describing: only authenticated users can be authorized, at least in my idea of auth systems....


 
I feel like I'm missing something, as I'm sure others have encountered cases similar to mine. Is there a better/DRY-er way to write scenarios like the ones I describe? Any suggestions would be greatly appreciated!

I wouldn't try to be too much DRY in the feature files: descriptiveness above dryness in my mind.....

Andrew Premdas

unread,
Mar 18, 2014, 10:24:00 AM3/18/14
to cu...@googlegroups.com
This ( http://pages.andrew.premdas.org/2011/11/18/consistency-in-features.html ) might be of some use in dealing with this. By widening the context to include the feature description, and even the path to the feature, you might be able to get a better idea of the `what` and `why` of this feature.

When you get situations like this where there is a background clause trying to get out, but there is a scenario or two getting in the way, then you probably have two (or more) features wanting to come out.

Here it seems that instead of trying to deal with all of access to feature x, in one feature, you have

1. Users who are not authenticated can't access feature X
2. Group access to feature X
3. Individual exclusion of a particular user to feature X, even though their group has access.

Making a seperate feature for 3 in particular would be a very good thing. This should aim to document the value that allowing this exclusion gives to the project. This will tie in with the work to deny a specific user permission to access feature X. Here you are likely to get a nice background e.g.

Background:

Background:
  Given
that the user is authenticated
 
And feature X is enabled for their group
 

Scenario: User accesses feature x
  When they attempt to access feature X
 
Then they access feature x


Scenario: User has been specifically excluded from feature X
  Given user has been specifically excluded from feature X
  When they attempt to access feature X
 
Then they receive an unauthorized error



All best

Andrew
 
 

--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
------------------------
Andrew Premdas

George Dinwiddie

unread,
Mar 18, 2014, 1:03:52 PM3/18/14
to cu...@googlegroups.com
Justin,

You might reconsider that generic "user."

On 3/17/14, 11:57 PM, Justin Holzer wrote:
> I am just getting started out with writing specs using Gherkin. I think
> it's great, but there is one case in particular where I am unsure of
> what the best practice is, and was hoping you all (the wonderful
> Cucumber community), could lend some advice.
>
> I have a feature in which most, but not all, of the scenarios are
> dependent on the following "Given" conditions:
>
> * The user must be authenticated
> * The feature must be enabled for the group that the user belongs to
> * The user must also be granted explicit permissions to access the
feature
>
> I have created scenarios to provide examples of what should happen in
> the cases where each one of the above conditions is not met...
>
> |
> Scenario: The user cannot access feature X because they are not
authenticated
> Given that the user is not authenticated
> When they attempt to access feature X
> Then they receive an unauthorized error

When an unauthenticated user attempts to access feature X
Then they receive an unauthorized error

>
> Scenario: The user cannot access feature X because it is disabled for
their
> group
> Given that the user is authenticated
> And feature X is disabled for their group
> When they attempt to access feature X
> Then they receive an unauthorized error

Given feature X is disabled for group "UnuthorizedGroup"
When an authenticated user of group "UnuthorizedGroup" attempts to
access feature X
...

BTW, what is "an unauthorized error?" Is that an error that's not
allowed? ;-) Phrasing and word choice matters.

>
> Scenario: The user cannot access feature X because they are not granted
> permission to access it
> Given that the user is authenticated
> And feature X is enabled for their group
> And the user is not granted permission to access feature X
> When they attempt to access feature X
> Then the receive an unauthorized notification
> |
>
> The first scenario above will be the only scenario in which the user is
> not authenticated/signed in. Is it truly necessary to reiterate that the
> user is authenticated in every other scenario? Can the fact that the
> user is authenticated safely be assumed in all scenarios other than the
> first? If not, is there a better way to indicate that it applies to all
> scenarios, except for one, without explicitly repeating it again and
again?

Another approach would be to create one feature file for access control,
and another for use of the feature itself.

>
> It also feels like the way that I have written the above scenarios is
> implying the order in which the conditions should be checked, which is
> not what I want to imply at all. These are high level requirements after
> all, not technical design documents.
>
> Similarly, for all scenarios other than the 3 mentioned above, it will
> be a "Given" that the user is authenticated, they have the feature
> enabled for their group, and they have permission to access it. Again,
> will it really be necessary to repeat these facts for every scenario
> (other than the 3 mentioned above)?
>
> I feel like I'm missing something, as I'm sure others have encountered
> cases similar to mine. Is there a better/DRY-er way to write scenarios
> like the ones I describe? Any suggestions would be greatly appreciated!

What are the other scenarios for the feature? I would concentrate on
those, first, and then worry about the authentication and authorization.
I find it easier to make meaningful scenarios when the user is trying to
do more than get beyond an error message.

- George

--
----------------------------------------------------------------------
* George Dinwiddie * http://blog.gdinwiddie.com
Software Development http://www.idiacomputing.com
Consultant and Coach http://www.agilemaryland.org
----------------------------------------------------------------------

Justin Holzer

unread,
Mar 18, 2014, 1:36:12 PM3/18/14
to cu...@googlegroups.com
The idea of splitting up the scenarios in to multiple features does sound appealing, and seems to make a great deal of sense. That would then make it possible to add in background information for each feature. The main downside to this approach though, is that it seems like over time you could end up accumulating a very large number of feature definitions. Perhaps this isn't such a bad thing. This is really the first time I've had the opportunity to create this type of documentation on a large scale, so I'm not sure if it makes more sense, from a management point of view, to favor grouping more scenarios in to fewer broadly scoped features, or spreading out scenarios over more, smaller and more concise, features.

I think I will give this approach a shot and see how it goes, and just tweak it as needed.

Thanks!

Justin

Justin Holzer

unread,
Mar 18, 2014, 1:41:50 PM3/18/14
to cu...@googlegroups.com
George,

I think your suggestion to break out the feature in to multiple, more narrowly scoped, features, similar to what Andrew suggested, is a good one. I'm going to give it a shot and see how it goes.

As for the "Then they receive an unauthorized notification" step, that was just a result of laziness and typing this all out at 12:30 am. I didn't want to copy and paste the actual feature, because it has business-specific language that probably wouldn't make any sense to someone not familiar with the product, so I just rewrote scenarios that followed the same general ideas. It was a poor choice of words, but it was intended to communicate that the user would be shown an error message stating that they aren't authorized to access the feature.

Thanks for the suggestions!

- Justin

Justin Holzer

unread,
Mar 18, 2014, 2:05:02 PM3/18/14
to cu...@googlegroups.com
Robert,

Thanks for the feedback. As has been suggested, I'm going to try splitting up the feature in to multiple, more narrowly scoped ones, and try using the feature background to communicate shared authentication and authorization rules. That sounds like the most reasonable approach to me. Also, seeing as how every response has suggested this approach, in some fashion, I would think there is some merit to the idea!

In a different file you can describe the authorization features and you can have functions/operations and groups in there and you can move the authentication step in the Background section as it is no more highly relevant to what you are describing: only authenticated users can be authorized, at least in my idea of auth systems....

I would definitely have my authentication-related features documented separately. While you are technically correct that an authorized user is almost always going to be an authenticated user, there is often a need to make a distinction between unauthenticated users and those who are authenticated but lack permission to access a feature

For instance, an unauthenticated user that attempts to access a feature, which requires authentication, may be automatically redirected to the log in screen. However, a user that is authenticated, but doesn't have permission, might be shown an error message instead, and not redirected to the log in screen. Within each feature I certainly don't want to rehash the authentication process, but I do want to make sure that it is communicated that authentication/sign-in is required in order to access a feature, along with any other permissions that may be required. There is great value in making sure that everyone involved in the product understands this, as security is a priority for everyone, from the product owner on down.

Thanks again!

Justin

Andrew Premdas

unread,
Mar 18, 2014, 2:07:20 PM3/18/14
to cu...@googlegroups.com
On 18 March 2014 17:36, Justin Holzer <jsho...@gmail.com> wrote:
> The idea of splitting up the scenarios in to multiple features does sound
> appealing, and seems to make a great deal of sense. That would then make it
> possible to add in background information for each feature. The main
> downside to this approach though, is that it seems like over time you could
> end up accumulating a very large number of feature definitions. Perhaps this
> isn't such a bad thing. This is really the first time I've had the
> opportunity to create this type of documentation on a large scale, so I'm
> not sure if it makes more sense, from a management point of view, to favor
> grouping more scenarios in to fewer broadly scoped features, or spreading
> out scenarios over more, smaller and more concise, features.

A couple fo things:

You are not creating documentation, you are making an active/living
map. One of the things it does is document, but really it does much
much more.

Generally as features mature and develop they want to become a little
narrower and more precise. This reflects the knowledge you gain from
implementing them. Also as a feature ages its purpose changes from
initiating and guiding development to more about supporting
maintenance, and providing tools for future development.

In practice if you won't end up with 'a very large number of feature
definitions' if you

1: don't create a giant monolith of an application
2: write features at a high level of abstraction
3: use unit tests where appropriate to do low-level testing
4: refactor frequently
Reply all
Reply to author
Forward
0 new messages