Discussion:
[Cucumber] [Gherkin] How do you specify features? Without repeating?
Add Reply
b***@gmail.com
2017-11-21 15:42:11 UTC
Reply
Permalink
Raw Message
Questions at bottom.

Alright, I have my own strengths and weaknesses, and I'd like to think I'm
adept at describing features through both Use Cases and Unit/subsystem
tests.

But I'm having trouble figuring out how Gherkin/Given-When-Then is meant to
be used with what I see as conflicting guidelines. Of course it doesn't
help when the community who created it (let alone wikipedia) has almost
nothing for a definition of GWT
(https://www.agilealliance.org/glossary/gwt), so I'm lost in searching for
help. Which is why I'm here.

It seems like Cucumber (and other tools) are dependent upon an implicit
agreement as to the size and scope of steps (I use "steps" to refer to
every executable line in a Scenario).

Since the devil is in the details, it seems like this would lead groups to
depend upon many assumptions which, ideally, would be resolved at some
point before implementation, perhaps even of the steps.

As an example, I'm looking at the Cucumber Book, the downloadable PDF from
gitbook (based off the github wiki, correct?). The snippet is:

Scenario: Successful sign up...
Given I have chosen to sign up
When I sign up with valid details
Then I should receive a confirmation email

Here we may have a wide variety of responsibilities for each line:
1. The Given's action may be a single click of a "sign up" link, or simply
a personal decision if the website gives the sign-up blanks on the front
page.
2. This When may take 3 entries and 30 seconds, or 100 entries, 30 minutes,
multiple external services and an email to complete.
3. "Then" includes assumptions like: there is a single email, or a primary
or a preferred for this purpose, as well as the content of said email - or
language, or timeliness, or...

In one way I appreciate the abstraction: this is perfect for the
brainstorming phase of a project, so that we identify what the broad
requirements are, system dependencies, etc., and we can flesh them out
later. But I have trouble seeing these given steps as specifications.

My primary concern is Step #2, the "When". Maybe it is the wording of it,
but it seems to me like it is naming another scenario.

Some will argue that scenarios and features should not refer to each
other... Don't you have to at least admit that the business rules from the
scenario have to be reproduced in the step definition for that Given?

Given that the community claims a Scenario should only ever have a single
"When", To do that, I guess you'd have a "SignUpWithValidDetails.feature"
filled with scenarios for every blank and control which could be used,
specifying rules governing each of them, as well as defining
interdependencies and their happy/sad paths. That could easily be several
hundred minute Scenarios, perhaps with the Background of just being on the
sign up input page.

However... then you'd still have to have some Scenario referring to the
aggregate of having valid inputs in all controls - which refers to all of
those minute scenarios in aggregate. Wouldn't you?

... And then many things happen in sequence, so there continues to be a
need for Scenarios to refer to other scenarios: X has to happen before Y...
Even if you're only referring to them by name "Given I logged in And..."


*My questions are*

A) do you manage to not have Scenarios/Features refer to each other?
B) does your group tend to have related Given, When, and Then step
definitions near each other so that changes to business rules in one
initiate changes to others?
C) do you tend to have collections of high-level tests ("Email on signup"),
and low-level tests (eg. validate input on the "name" textbox)? How do you
organize them: different files? Tags?
D) does your group skip the "But" steps which explicitly exclude certain
states or inputs, and instead rely on Scenario titles (or Given steps?) to
identify related special cases? Doesn't skipping "But"s mean there's an
implicit precedence for tests' correctness?

Thanks!
--
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+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Andrew Premdas
2017-11-22 14:37:31 UTC
Reply
Permalink
Raw Message
I'll try and pick out various things

# Wrong assumptions

You said 1. The Given's action may be a single click of a "sign up" link,
or simply a personal decision if the website gives the sign-up blanks on
the front page.

No not really. A Given is all about doing anything necessary to ensure that
your When can be a single user interaction. Given's generally build on
behavior previously explored by a When. For example a step

GIven 'I am signed in'

will build on the behaviour first explored by the step

When 'I sign in'

And similarly because we can't sign in unless we have registered the step

Given 'I am registered'

in your sign up scenario will build upon on the step 'When I register' in
your registration scenario.

Givens often build upon When's by optimizing HOW things are done to remove
user interactions. You don't need to fill in a registration form to be
registered, you can just call you apps register_me service with the correct
params (fast and good) or write a User record directly to the database
(fast and not so good).

You said 2. This When may take 3 entries and 30 seconds, or 100 entries, 30
minutes, multiple external services and an email to complete.

No you misunderstand what a When is. A When is a single user interaction,
mostly these are:

1. a user filling in a form and clicking submit
2. a user interacting with some other part of the UI (clicking a link)
3. a single api call

All When's should be single call and response, compound when's are an
anti-pattern. e.g. you should not complete two parts of a wizard in a When

You have to design When's to complete very quickly, this reflects on how
you should design API calls and web POSTS to respond very quickly.

You said 3. "Then" includes assumptions like: there is a single email, or a
primary or a preferred for this purpose, as well as the content of said
email - or language, or timeliness, or...

All Thens are doing is looking for some indication that something is done
(or perhaps that something is going to be done). All scenarios are run in a
Test World, and that Test World is by definition a simplified version of
the actual world your application will run in.

The fundamental problem you have with scenarios having to build on
scenarios is understanding that this has nothing to do with Cucumber.
Instead its all about language, naming, encapsulation and abstraction. No
matter how complex something is we can name it. Once we have named in we
can encapsulate it into a call. Once we have that call we can use that
behavior without having to know anything about HOW its implemented

So for the following ecommerce scenario

Scenario: Reorder favorite order
Given I have a favorite order
When I reorder my favorite order
Then I ...

and we can implement

Given 'I have a favorite order' do
create_favourite_order(user: @i)
end

and create_favourite_order will call code that creates products, ensures
that @i is registered, orders the same things several times for the me etc.
etc., but all of that stuff is just using existing behavior.


Now onto your questions:

A) do you manage to not have Scenarios/Features refer to each other?

There is a difference between referring to each other and linking
execution. The whole point of having a scenario 'I can register' is so that
later on I can use that behavior to do other things like sign in. So I will
have

Feature: Registration
As a visitor
I want to register
So I can ....

Scenario: I can register
Given I am a visitor
When I register
Then I should be registered

and then I'll have

Feature: Sign in
As a registered user
I want to sign in
So I can ...

Scenario: Sign in
Given I am registered
When I sign in
Then I should be signed in

Now of course sign in refers to registration you couldn't write scenarios
without doing this.

B) does your group tend to have related Given, When, and Then step
definitions near each other so that changes to business rules in one
initiate changes to others?

Step definitions can and should be made irrelevant. I'll show you how and
explain why. A good step definition should be a single call that delegates
HOW the step definition is implemented to something else e.g.

When 'I sign in' do
sign_in user: @i
end

If you do this for all step definitions (particularly Givens and Whens),
what becomes important is the methods you delegate to and their method
signatures.
So if you have another step definition

When 'I login' do
sing_in user: @i
end

then that's not an issue. Similarly you can have

When 'Fred signs in' do
sign_in user: @fred
end

Now you clearly its a good idea to keep related methods together e.g.

module SignInStepHelper
def sign_in(user:)
...

def register(user:
...
# should this be here or in RegisterStepHelper?


but thats just now a simple question of code organisation (its nothing
special to Cucumber). You don't really need to worry so much about
organizing step definitions when you do this because tools can find them
for you.

C) do you tend to have collections of high-level tests ("Email on signup"),
and low-level tests (eg. validate input on the "name" textbox)? How do you
organize them: different files? Tags?

Cucumber is not a testing tool and scenarios should not be seen as tests.
When used effectively Cucumber contains a relatively small number of high
level integrations that are sufficient to get certain Behavior developed.
Any testing that is in any way exhaustive or low level should be done with
something else. The run-time costs of scenarios and the overall costs of
writing scenarios to do exhaustive or low level testing are too high to
make them worth while to do using Cucumber.

D) does your group skip the "But" steps which explicitly exclude certain
states or inputs, and instead rely on Scenario titles (or Given steps?) to
identify related special cases? Doesn't skipping "But"s mean there's an
implicit precedence for tests' correctness?

Cucumber is not about proving things are correct. Its not a testing tool.
Its a tool to drive the development of behavior. Done well the things it
produces can do some of the things that tests do. They can

- provide some regression (give some confidence that the application is
working in roughly the same way as it was previously)
- facilitate refactoring
- give some indication that some behaviour is implemented e.g. that you can
login

They cannot prove anything is correct. If you don't review your behavior in
addition to getting your scenarios to go green you know nothing about your
application.


Hope all of this helps. I know alot of the answers start with the same
thing "Cucumber is not a testing tool". This really is a very important
thing to understand.
Post by b***@gmail.com
Questions at bottom.
Alright, I have my own strengths and weaknesses, and I'd like to think I'm
adept at describing features through both Use Cases and Unit/subsystem
tests.
But I'm having trouble figuring out how Gherkin/Given-When-Then is meant
to be used with what I see as conflicting guidelines. Of course it doesn't
help when the community who created it (let alone wikipedia) has almost
nothing for a definition of GWT (https://www.agilealliance.
org/glossary/gwt), so I'm lost in searching for help. Which is why I'm
here.
It seems like Cucumber (and other tools) are dependent upon an implicit
agreement as to the size and scope of steps (I use "steps" to refer to
every executable line in a Scenario).
Since the devil is in the details, it seems like this would lead groups to
depend upon many assumptions which, ideally, would be resolved at some
point before implementation, perhaps even of the steps.
As an example, I'm looking at the Cucumber Book, the downloadable PDF from
Scenario: Successful sign up...
Given I have chosen to sign up
When I sign up with valid details
Then I should receive a confirmation email
1. The Given's action may be a single click of a "sign up" link, or simply
a personal decision if the website gives the sign-up blanks on the front
page.
2. This When may take 3 entries and 30 seconds, or 100 entries, 30
minutes, multiple external services and an email to complete.
3. "Then" includes assumptions like: there is a single email, or a primary
or a preferred for this purpose, as well as the content of said email - or
language, or timeliness, or...
In one way I appreciate the abstraction: this is perfect for the
brainstorming phase of a project, so that we identify what the broad
requirements are, system dependencies, etc., and we can flesh them out
later. But I have trouble seeing these given steps as specifications.
My primary concern is Step #2, the "When". Maybe it is the wording of it,
but it seems to me like it is naming another scenario.
Some will argue that scenarios and features should not refer to each
other... Don't you have to at least admit that the business rules from the
scenario have to be reproduced in the step definition for that Given?
Given that the community claims a Scenario should only ever have a single
"When", To do that, I guess you'd have a "SignUpWithValidDetails.feature"
filled with scenarios for every blank and control which could be used,
specifying rules governing each of them, as well as defining
interdependencies and their happy/sad paths. That could easily be several
hundred minute Scenarios, perhaps with the Background of just being on the
sign up input page.
However... then you'd still have to have some Scenario referring to the
aggregate of having valid inputs in all controls - which refers to all of
those minute scenarios in aggregate. Wouldn't you?
... And then many things happen in sequence, so there continues to be a
need for Scenarios to refer to other scenarios: X has to happen before Y...
Even if you're only referring to them by name "Given I logged in And..."
*My questions are*
A) do you manage to not have Scenarios/Features refer to each other?
B) does your group tend to have related Given, When, and Then step
definitions near each other so that changes to business rules in one
initiate changes to others?
C) do you tend to have collections of high-level tests ("Email on
signup"), and low-level tests (eg. validate input on the "name" textbox)?
How do you organize them: different files? Tags?
D) does your group skip the "But" steps which explicitly exclude certain
states or inputs, and instead rely on Scenario titles (or Given steps?) to
identify related special cases? Doesn't skipping "But"s mean there's an
implicit precedence for tests' correctness?
Thanks!
--
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
For more options, visit https://groups.google.com/d/optout.
--
------------------------
Andrew Premdas
blog.andrew.premdas.org
--
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+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
QARunner
2017-11-22 18:35:54 UTC
Reply
Permalink
Raw Message
Hi,

perhaps it helps to follow some simple rules (but not so simple to follow,
be aware of that):

Keep your scenarios free from technical implementation and concentrate on
the logical behaviour. No reuse of scenarios or GWT-steps on this level. No
unnecessary details in testdata that is irrelevant for your behaviour (see
A).

Implement your GWT-steps in step definitions, that are easy to follow and
transparent enough to understand what your intention is. Perhaps you even
use another level of implementation underneath for the real technical
stuff, like pageobjects. We define some model classes to reuse some things
that need to be done in multiple step definitions (is that your B?)

Manage your features and scenarios in file hierarchies and by using tags to
collect scenarios in different features (see C)

Hold on to your test goal and stay focused... most of the time in cucumber
it's more important WHAT you will do and not HOW it is done (especially in
every detail). That keeps your scenarios clear and well separated You want
clarity about what is tested, and perhaps what not! You do a high level
test for higher purposes, so don't clutter it with low level details. Those
tests have to be done elsewhere - and perhaps not controlled by cucumber.
You have no other way if you are using ui tests... you have to move these
things away from ui to a component level.

So...

A) Scenarios/Features refer to each other?
Use tags and no references or even dependencies between features and
scenarios

B) related Given, When, and Then step?
Still don't get what you mean with related GWTs. The only relation in GWT I
see is the problematic relation in using same data in those steps and
transferring them between step definitions.

C) collections of high-level tests and low-level tests
Yes you can have those, but tag them differently because probably the
technical layer like ui- or API-level for execution is totally different
(and execution speed too)
You can of course use different feature files if you want

,D) "But" steps
Never used the But steps. It seems to be more of a cosmetic nature for me,
to be able to better describe logical business behaviour.
The distinction from other scenarios w/o Buts should be made visible by a
good scenario title!
--
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+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...