Discussion:
Reuse of Cucumber Features
(too old to reply)
Williams, Wesley
2009-04-08 09:31:32 UTC
Permalink
All,



I know this is an older post but I have a similar but different set of
scenarios I need to handle. I have a set of flight related scheduling
features, such as delay, reschedule, and cancel, each with multiple
scenarios that have an effect on later flights in the schedule (there
are a lot of scenarios actually). What (I think J) I need is a set of
flights that I can reuse, in a Background: given section, by all of
these features and scenarios, that is defined in a way that is reusable
and visible in each of the feature definitions.



Is this possible? Is there a better way to do this?



Example:



Feature: Delay flights with down line adjustments

As a flight scheduler

I want to delay a flight and have the down line flights adjusted for
different periods

So I can more quickly update a schedule when events happen



Background:

Given I have the following flights scheduled:

|aircraft | flight number | dept date | dept time |

| XX1 | XX0001 | 03Mar2009 | 1000 |

| XX1 | XX0002 | 03Mar2009 | 1400 |

| XX1 | XX0003 | 03Mar2009 | 2100 |

| XX1 | XX0004 | 04Mar2009 | 1000 |



Scenario: delay flights with down line adjustments for same dept
date as delayed flight

When I delay flight XX001 by 5 mins

Then XX001 departs at 1005

Then XX002 departs at 1405

Then XX003 departs at 2105

Then XX004 departs at 1000



OR



Scenario: delay flights with down line adjustments for same dept
date as delayed flight

When I delay flight XX001 by 5 mins

Then the scheduled flight should be

|aircraft | flight number | dept date | dept time |

| XX1 | XX0001 | 03Mar2009 | 1005 |

| XX1 | XX0002 | 03Mar2009 | 1405 |

| XX1 | XX0003 | 03Mar2009 | 2105 |

| XX1 | XX0004 | 04Mar2009 | 1000 |



There are many more scenarios.



Is there a nice way to removed the duplication that is here, especially
since I will need a similar set of flights for other scheduling change
scenarios? Does anyone see a nice way to simplify the scenarios?



Great tool by the way.



Thanks,

Wes



Subject: [rspec-users] Reuse of Cucumber Features



+lots :)

Generally when we have problems with features its because we are trying
to
do to much at once. So in your case date entry is being complicated by
different contexts, birth and incident. One of the tennents of BDD is to
write the simplest thing you can to make you feature pass. I think
another
one should be "first of all write the simplest scenarios". So taking one
of
your examples

Scenario: Enter Valid Incident
When I fill incident correctly
I should recieve a confirmation

Then your incident step can be something like

When /^I fill incident correctly$/ do
fill_in("incident[name]", :with => ...
...
end

If you wanted to specify validation in features you could do a step like

When /^I fill incident correctly except$/ do |field|
When "I fill in incident correctly"
fill_in("incident[#{field}]", :with => ''
end

now you can create new features like

Scenario: Enter Valid Incident with no date
When I fill incident correctly except date
I should recieve an error

With a bit more trickery you could have

When I fill incident correctly except date which is xxx

Taking this approach you can build incrementally quite complex
validation
features whilst stll keeping each scenario simple and focused on one
thing.
Whether you should do this with features or put this detail somewhere
else
is another question entirely.

On another point with dates have you considered international issues.
All
the dates you've given in your example are valid (technically) there
just
not in the format you prefer. Also consider that the invalidity of
dates
might be context dependant e.g. an incident date in the future, an
appointment in the past.

HTH

Andrew


2008/12/14 Pat Maddox <pergesu at gmail.com
<http://rubyforge.org/mailman/listinfo/rspec-users> >
Hi Steve,
I likely would only write two scenarios, one for a valid date and one
for an invalid one. Then I would write object-level specs to
determine
what a valid date is. Extract this to a validator that you can reuse
throughout your model.
If it's important that you write features for each potential invalid
date format (because you want to communicate them with the customer)
then I would write a feature file similar to what you show...but it
would be focused only on the date, I wouldn't mention patients or
incidents at all. Date entry seems to be an important concept in your
application, so I would write one feature that specifies how I expect
date entry to work, and then I can just write valid/invalid dates for
patient and incident features. Same idea as the first paragraph, but
using features instead of specs.
Pat
"Steve Molitor" <stevemolitor at gmail.com
Thanks -- that gets me closer. Here's an example. Let's say I have
two
features, 'Create new patient' and 'Create new incident'. To
create a new patient you have to enter a valid birth date. To
create a
new patient you must enter a valid birth date. To create a new
incident you must enter a valid incident date. The rules for date
entry
Feature: Date entry
Scenario: Invalid month
When I fill in the date value with "13/01/2000"
I should see "Invalid date..."
Scenario: Invalid year (not 4 digits)
When I fill in the date value with "13/01/00"
I should see "Invalid date..."
Scenario: Separate with slashes (ok)
When I fill in the date value with "01/13/2000"
I should see "valid date..."
Scenario: Separate with dashes (ok)
When I fill in the date value with "01-13-2000"
I should see "valid date..."
.... etc....
Given the above, how should I write the 'create new patient' and
'create
new incident' features? I don't want to copy and paste all the
date related scenarios, but I do want to specify (and test) that the
patient birth date and incident date fields conform to the general
date
rules. Here's how the 'create new patient' and 'create new
incident'
Feature: Create new Patient
Scenario: Enter invalid birth date
Given I fill in "birth date" with "13/01/2000"
And I fill in "patient name" with "Sam Smith"
When I press "Save"
I should see "Invalid birth date '13/01/2000'"
Scenario: Enter valid birth date, valid name
Given I fill in "birth date" with "01/13/2000"
And I fill in "patient name" with "Sam Smith"
When I press "Save"
I should see "Patient Created Successfully"
Scenario: Enter valid birth date with dashses.....
-------
Feature: Create new Incident
Scenario: Enter invalid incident date
Given I fill in "incident" with "13/01/2000"
And I fill in "supervisor" with "Sam Smith"
When I press "Save"
I should see "Invalid incident date '13/01/2000'"
Scenario: Enter valid incident date, valid supervisor
Given I fill in "incident date" with "01/13/2000"
And I fill in "supervisor" with "Sam Smith"
When I press "Save"
I should see "Incident Created Successfully"
Scenario: Enter valid incident date with dashes....
-----
Am I making sense? I want to specify the date in the features, as
there
may be extra requirements like birth dates can not be in the future
in addition to the generic date requirements. And I want to
validate
that the form checks for valid dates, displays the appropriate error
message when invalid, and uses the common rules for parsing. But I
don't
want to copy and paste those scenarios in every feature. I think
reusing steps as you mention is probably the solution but I'm stuck
on
how to word it and put it together in my case.
Steve
On Sun, Dec 14, 2008 at 8:41 AM, Matt Wynne <matt at mattwynne.net
What's the best way to handle a requirement that shows up as
a
sub-requirement requirement in other features? For example let's say
users can enter dates in various forms throughout my
application.
There is one set of global rules specifying the formats in which
dates may be entered, and how they are interpreted. I put
that
in one feature. In various other features, like 'Create new
patient', one can enter dates, like the patient's birth
date. I
want to do something like 'and the date entry shall follow the
normal rules' but I'm not sure how to do that in an example
driven way, without copying and pasting from other features.
Does my question make sense? Any suggestions?
Do you know that you can call steps within steps?
http://blog.mattwynne.net/2008/11/14/dry-up-your-cucumber-steps/
Is that what you're looking for?
Matt Wynne
http://blog.mattwynne.net <http://blog.mattwynne.net>
http://www.songkick.com
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
<http://rubyforge.org/mailman/listinfo/rspec-users>
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
<http://rubyforge.org/mailman/listinfo/rspec-users>
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
<http://rubyforge.org/mailman/listinfo/rspec-users>
http://rubyforge.org/mailman/listinfo/rspec-users
Matt Wynne
2009-04-09 07:57:47 UTC
Permalink
Post by Williams, Wesley
All,
I know this is an older post but I have a similar but different set
of scenarios I need to handle. I have a set of flight related
scheduling features, such as delay, reschedule, and cancel, each
with multiple scenarios that have an effect on later flights in the
schedule (there are a lot of scenarios actually). What (I think J)
I need is a set of flights that I can reuse, in a Background: given
section, by all of these features and scenarios, that is defined in
a way that is reusable and visible in each of the feature definitions.
Is this possible? Is there a better way to do this?
Feature: Delay flights with down line adjustments
As a flight scheduler
I want to delay a flight and have the down line flights adjusted
for different periods
So I can more quickly update a schedule when events happen
|aircraft | flight number | dept date | dept time |
| XX1 | XX0001 | 03Mar2009 | 1000 |
| XX1 | XX0002 | 03Mar2009 | 1400 |
| XX1 | XX0003 | 03Mar2009 | 2100 |
| XX1 | XX0004 | 04Mar2009 | 1000 |
Scenario: delay flights with down line adjustments for same dept
date as delayed flight
When I delay flight XX001 by 5 mins
Then XX001 departs at 1005
Then XX002 departs at 1405
Then XX003 departs at 2105
Then XX004 departs at 1000
OR
Scenario: delay flights with down line adjustments for same dept
date as delayed flight
When I delay flight XX001 by 5 mins
Then the scheduled flight should be
|aircraft | flight number | dept date | dept time |
| XX1 | XX0001 | 03Mar2009 | 1005 |
| XX1 | XX0002 | 03Mar2009 | 1405 |
| XX1 | XX0003 | 03Mar2009 | 2105 |
| XX1 | XX0004 | 04Mar2009 | 1000 |
There are many more scenarios.
Is there a nice way to removed the duplication that is here,
especially since I will need a similar set of flights for other
scheduling change scenarios? Does anyone see a nice way to simplify
the scenarios?
Great tool by the way.
Thanks,
Wes
Have you seen this?

http://www.benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories/

Another way to remove duplication (and noise) from Cucumber steps is
the hide the details in the Ruby code that implements the step, and
write a much more general step in the feature file like this:

Given there are 3 flights departing on the same day
And the flights all leave at different times
And there is another flight leaving on the following day
When the earliest flight is delayed by 5 mins
Then the flights on the first day should all be delayed by 5 minutes
And the flight on the second day should be unaffected

These kind of steps can be clearer to read, but the trade-off is that
your underlying step code gets more complex as you start writing logic
to deliver these specific scenarios. Still, if you're clever about it,
these 'declarative' steps can still be pretty re-usable.

HTH,
Matt
Post by Williams, Wesley
Subject: [rspec-users] Reuse of Cucumber Features
+lots :)
Generally when we have problems with features its because we are
trying to
do to much at once. So in your case date entry is being complicated by
different contexts, birth and incident. One of the tennents of BDD is to
write the simplest thing you can to make you feature pass. I think
another
one should be "first of all write the simplest scenarios". So taking
one of
your examples
Scenario: Enter Valid Incident
When I fill incident correctly
I should recieve a confirmation
Then your incident step can be something like
When /^I fill incident correctly$/ do
fill_in("incident[name]", :with => ...
...
end
If you wanted to specify validation in features you could do a step like
When /^I fill incident correctly except$/ do |field|
When "I fill in incident correctly"
fill_in("incident[#{field}]", :with => ''
end
now you can create new features like
Scenario: Enter Valid Incident with no date
When I fill incident correctly except date
I should recieve an error
With a bit more trickery you could have
When I fill incident correctly except date which is xxx
Taking this approach you can build incrementally quite complex
validation
features whilst stll keeping each scenario simple and focused on one
thing.
Whether you should do this with features or put this detail
somewhere else
is another question entirely.
On another point with dates have you considered international
issues. All
the dates you've given in your example are valid (technically) there
just
not in the format you prefer. Also consider that the invalidity of
dates
might be context dependant e.g. an incident date in the future, an
appointment in the past.
HTH
Andrew
2008/12/14 Pat Maddox <pergesu at gmail.com>
Hi Steve,
I likely would only write two scenarios, one for a valid date and
one
for an invalid one. Then I would write object-level specs to
determine
what a valid date is. Extract this to a validator that you can
reuse
throughout your model.
If it's important that you write features for each potential invalid
date format (because you want to communicate them with the customer)
then I would write a feature file similar to what you show...but it
would be focused only on the date, I wouldn't mention patients or
incidents at all. Date entry seems to be an important concept in
your
application, so I would write one feature that specifies how I
expect
date entry to work, and then I can just write valid/invalid dates
for
patient and incident features. Same idea as the first paragraph,
but
using features instead of specs.
Pat
Thanks -- that gets me closer. Here's an example. Let's say I
have two
features, 'Create new patient' and 'Create new incident'. To
create a new patient you have to enter a valid birth date. To
create a
new patient you must enter a valid birth date. To create a new
incident you must enter a valid incident date. The rules for
date entry
Feature: Date entry
Scenario: Invalid month
When I fill in the date value with "13/01/2000"
I should see "Invalid date..."
Scenario: Invalid year (not 4 digits)
When I fill in the date value with "13/01/00"
I should see "Invalid date..."
Scenario: Separate with slashes (ok)
When I fill in the date value with "01/13/2000"
I should see "valid date..."
Scenario: Separate with dashes (ok)
When I fill in the date value with "01-13-2000"
I should see "valid date..."
.... etc....
Given the above, how should I write the 'create new patient' and
'create
new incident' features? I don't want to copy and paste all the
date related scenarios, but I do want to specify (and test) that
the
patient birth date and incident date fields conform to the general
date
rules. Here's how the 'create new patient' and 'create new
incident'
Feature: Create new Patient
Scenario: Enter invalid birth date
Given I fill in "birth date" with "13/01/2000"
And I fill in "patient name" with "Sam Smith"
When I press "Save"
I should see "Invalid birth date '13/01/2000'"
Scenario: Enter valid birth date, valid name
Given I fill in "birth date" with "01/13/2000"
And I fill in "patient name" with "Sam Smith"
When I press "Save"
I should see "Patient Created Successfully"
Scenario: Enter valid birth date with dashses.....
-------
Feature: Create new Incident
Scenario: Enter invalid incident date
Given I fill in "incident" with "13/01/2000"
And I fill in "supervisor" with "Sam Smith"
When I press "Save"
I should see "Invalid incident date '13/01/2000'"
Scenario: Enter valid incident date, valid supervisor
Given I fill in "incident date" with "01/13/2000"
And I fill in "supervisor" with "Sam Smith"
When I press "Save"
I should see "Incident Created Successfully"
Scenario: Enter valid incident date with dashes....
-----
Am I making sense? I want to specify the date in the features,
as there
may be extra requirements like birth dates can not be in the future
in addition to the generic date requirements. And I want to
validate
that the form checks for valid dates, displays the appropriate error
message when invalid, and uses the common rules for parsing.
But I don't
want to copy and paste those scenarios in every feature. I think
reusing steps as you mention is probably the solution but I'm
stuck on
how to word it and put it together in my case.
Steve
On Sun, Dec 14, 2008 at 8:41 AM, Matt Wynne <matt at
What's the best way to handle a requirement that shows
up as a
sub-requirement requirement in other features? For example let's
say
users can enter dates in various forms throughout my
application.
There is one set of global rules specifying the formats in which
dates may be entered, and how they are interpreted. I
put that
in one feature. In various other features, like 'Create new
patient', one can enter dates, like the patient's birth
date. I
want to do something like 'and the date entry shall follow the
normal rules' but I'm not sure how to do that in an
example
driven way, without copying and pasting from other features.
Does my question make sense? Any suggestions?
Do you know that you can call steps within steps?
http://blog.mattwynne.net/2008/11/14/dry-up-your-cucumber-steps/
Is that what you're looking for?
Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
http://rubyforge.org/mailman/listinfo/rspec-users
Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com
Matthew Krom
2009-04-09 12:43:35 UTC
Permalink
Two other brainstorms:

Brainstorm 1:
Given an empty flights database
And aircraft XX1 flight number XX0001 departs on 03Mar2009 at 1000
And aircraft XX1 flight number XX0002 departs on 03Mar2009 at 1400
And aircraft XX1 flight number XX0003 departs on 03Mar2009 at 2100

Brainstorm 2:
# Sets up all the flights in your scenario
Given flight database scenario A

In #2, you have to reference separate documentation on what is contained
within scenario A. This may or may not be acceptable to your process, but
it can work quite well if you are comfortable referring to the separate
documentation to keep things straight.

Matt Krom
Post by Matt Wynne
Post by Williams, Wesley
I know this is an older post but I have a similar but different set of
scenarios I need to handle. I have a set of flight related scheduling
features, such as delay, reschedule, and cancel, each with multiple
scenarios that have an effect on later flights in the schedule (there are a
lot of scenarios actually). What (I think J) I need is a set of flights
that I can reuse, in a Background: given section, by all of these features
and scenarios, that is defined in a way that is reusable and visible in each
of the feature definitions.
Is this possible? Is there a better way to do this?
Feature: Delay flights with down line adjustments
As a flight scheduler
I want to delay a flight and have the down line flights adjusted for
different periods
So I can more quickly update a schedule when events happen
|aircraft | flight number | dept date | dept time |
| XX1 | XX0001 | 03Mar2009 | 1000 |
| XX1 | XX0002 | 03Mar2009 | 1400 |
| XX1 | XX0003 | 03Mar2009 | 2100 |
| XX1 | XX0004 | 04Mar2009 | 1000 |
Scenario: delay flights with down line adjustments for same dept date
as delayed flight
When I delay flight XX001 by 5 mins
Then XX001 departs at 1005
Then XX002 departs at 1405
Then XX003 departs at 2105
Then XX004 departs at 1000
OR
Scenario: delay flights with down line adjustments for same dept date
as delayed flight
When I delay flight XX001 by 5 mins
Then the scheduled flight should be
|aircraft | flight number | dept date | dept time |
| XX1 | XX0001 | 03Mar2009 | 1005 |
| XX1 | XX0002 | 03Mar2009 | 1405 |
| XX1 | XX0003 | 03Mar2009 | 2105 |
| XX1 | XX0004 | 04Mar2009 | 1000 |
There are many more scenarios.
Is there a nice way to removed the duplication that is here, especially
since I will need a similar set of flights for other scheduling change
scenarios? Does anyone see a nice way to simplify the scenarios?
Great tool by the way.
Thanks,
Wes
Have you seen this?
http://www.benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories/
Another way to remove duplication (and noise) from Cucumber steps is the
hide the details in the Ruby code that implements the step, and write a much
Given there are 3 flights departing on the same day
And the flights all leave at different times
And there is another flight leaving on the following day
When the earliest flight is delayed by 5 mins
Then the flights on the first day should all be delayed by 5 minutes
And the flight on the second day should be unaffected
These kind of steps can be clearer to read, but the trade-off is that your
underlying step code gets more complex as you start writing logic to deliver
these specific scenarios. Still, if you're clever about it, these
'declarative' steps can still be pretty re-usable.
HTH,
Matt
Williams, Wesley
2009-04-09 13:22:20 UTC
Permalink
Matt,



I am open to referring to separate documentation/scenario. It would be nice if I can optionally make it appear in the tests but that is a nice to have. Is this just an example/idea or is it possible to do this currently?



Thanks,

Wes



From: rspec-users-***@rubyforge.org [mailto:rspec-users-***@rubyforge.org] On Behalf Of Matthew Krom
Sent: Thursday, April 09, 2009 2:44 PM
To: rspec-users
Subject: Re: [rspec-users] Reuse of Cucumber Features



Two other brainstorms:

Brainstorm 1:
Given an empty flights database
And aircraft XX1 flight number XX0001 departs on 03Mar2009 at 1000
And aircraft XX1 flight number XX0002 departs on 03Mar2009 at 1400
And aircraft XX1 flight number XX0003 departs on 03Mar2009 at 2100

Brainstorm 2:
# Sets up all the flights in your scenario
Given flight database scenario A

In #2, you have to reference separate documentation on what is contained within scenario A. This may or may not be acceptable to your process, but it can work quite well if you are comfortable referring to the separate documentation to keep things straight.

Matt Krom




I know this is an older post but I have a similar but different set of scenarios I need to handle. I have a set of flight related scheduling features, such as delay, reschedule, and cancel, each with multiple scenarios that have an effect on later flights in the schedule (there are a lot of scenarios actually). What (I think J) I need is a set of flights that I can reuse, in a Background: given section, by all of these features and scenarios, that is defined in a way that is reusable and visible in each of the feature definitions.

Is this possible? Is there a better way to do this?

Example:

Feature: Delay flights with down line adjustments
As a flight scheduler
I want to delay a flight and have the down line flights adjusted for different periods
So I can more quickly update a schedule when events happen

Background:
Given I have the following flights scheduled:
|aircraft | flight number | dept date | dept time |
| XX1 | XX0001 | 03Mar2009 | 1000 |
| XX1 | XX0002 | 03Mar2009 | 1400 |
| XX1 | XX0003 | 03Mar2009 | 2100 |
| XX1 | XX0004 | 04Mar2009 | 1000 |

Scenario: delay flights with down line adjustments for same dept date as delayed flight
When I delay flight XX001 by 5 mins
Then XX001 departs at 1005
Then XX002 departs at 1405
Then XX003 departs at 2105
Then XX004 departs at 1000

OR

Scenario: delay flights with down line adjustments for same dept date as delayed flight
When I delay flight XX001 by 5 mins
Then the scheduled flight should be
|aircraft | flight number | dept date | dept time |
| XX1 | XX0001 | 03Mar2009 | 1005 |
| XX1 | XX0002 | 03Mar2009 | 1405 |
| XX1 | XX0003 | 03Mar2009 | 2105 |
| XX1 | XX0004 | 04Mar2009 | 1000 |

There are many more scenarios.

Is there a nice way to removed the duplication that is here, especially since I will need a similar set of flights for other scheduling change scenarios? Does anyone see a nice way to simplify the scenarios?

Great tool by the way.

Thanks,
Wes



Have you seen this?

http://www.benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories/

Another way to remove duplication (and noise) from Cucumber steps is the hide the details in the Ruby code that implements the step, and write a much more general step in the feature file like this:

Given there are 3 flights departing on the same day
And the flights all leave at different times
And there is another flight leaving on the following day
When the earliest flight is delayed by 5 mins
Then the flights on the first day should all be delayed by 5 minutes
And the flight on the second day should be unaffected

These kind of steps can be clearer to read, but the trade-off is that your underlying step code gets more complex as you start writing logic to deliver these specific scenarios. Still, if you're clever about it, these 'declarative' steps can still be pretty re-usable.

HTH,
Matt
Rick DeNatale
2009-04-09 13:19:05 UTC
Permalink
Post by Matt Wynne
Another way to remove duplication (and noise) from Cucumber steps is the
hide the details in the Ruby code that implements the step, and write a much
Given there are 3 flights departing on the same day
And the flights all leave at different times
And there is another flight leaving on the following day
When the earliest flight is delayed by 5 mins
Then the flights on the first day should all be delayed by 5 minutes
And the flight on the second day should be unaffected
These kind of steps can be clearer to read, but the trade-off is that your
underlying step code gets more complex as you start writing logic to deliver
these specific scenarios. Still, if you're clever about it, these
'declarative' steps can still be pretty re-usable.
I've gone down a similar road before, albeit with the old story runner
rather than Cucumber, and I'm not sure how far I'd push it.

That trade-off starts to get onerous. You spend a lot of time debugging
your steps to convince yourself that "the flight on the second day" maps to
"another flight leaving on the following day" when you reuse the steps in
other cases. I found myself wanting to do meta bdd on my story code!
--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
Williams, Wesley
2009-04-09 13:42:48 UTC
Permalink
I have similar concerns. I am coming from a background in Fit/FitNesse
so I am use to the table idea but I am not completely convinced it is
better. I really appreciate all the feedback I am getting though, great
community. I bought 'The Rspec Book' which is what got me started
looking at the tool. More chapters please. J



I do think being able to use multiple scenarios together would be nice
but I do see the issues and danger and dangers of allowing scenario
dependencies. Like all dependencies they make change hard.



Thanks again for all the feedback and assistance.



Wes





From: rspec-users-bounces-***@public.gmane.org
[mailto:rspec-users-bounces-***@public.gmane.org] On Behalf Of Rick DeNatale
Sent: Thursday, April 09, 2009 3:19 PM
To: rspec-users
Subject: Re: [rspec-users] Reuse of Cucumber Features



On Thu, Apr 9, 2009 at 3:57 AM, Matt Wynne <matt-***@public.gmane.org> wrote:


Another way to remove duplication (and noise) from Cucumber steps is the
hide the details in the Ruby code that implements the step, and write a
much more general step in the feature file like this:

Given there are 3 flights departing on the same day
And the flights all leave at different times
And there is another flight leaving on the following day
When the earliest flight is delayed by 5 mins
Then the flights on the first day should all be delayed by 5
minutes
And the flight on the second day should be unaffected

These kind of steps can be clearer to read, but the trade-off is that
your underlying step code gets more complex as you start writing logic
to deliver these specific scenarios. Still, if you're clever about it,
these 'declarative' steps can still be pretty re-usable.



I've gone down a similar road before, albeit with the old story runner
rather than Cucumber, and I'm not sure how far I'd push it.



That trade-off starts to get onerous. You spend a lot of time debugging
your steps to convince yourself that "the flight on the second day" maps
to "another flight leaving on the following day" when you reuse the
steps in other cases. I found myself wanting to do meta bdd on my story
code!
--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
Williams, Wesley
2009-04-09 13:29:28 UTC
Permalink
Matt,

Hmm, I think this is one way to do it. I will need to get my customer
to think differently about defining the requirements. They really like
the tables.

Thanks,
Wes

-----Original Message-----
From: rspec-users-bounces-***@public.gmane.org
[mailto:rspec-users-bounces-***@public.gmane.org] On Behalf Of Matt Wynne
Sent: Thursday, April 09, 2009 9:58 AM
To: rspec-users
Subject: Re: [rspec-users] Reuse of Cucumber Features
Post by Williams, Wesley
All,
I know this is an older post but I have a similar but different set
of scenarios I need to handle. I have a set of flight related
scheduling features, such as delay, reschedule, and cancel, each
with multiple scenarios that have an effect on later flights in the
schedule (there are a lot of scenarios actually). What (I think J)
I need is a set of flights that I can reuse, in a Background: given
section, by all of these features and scenarios, that is defined in
a way that is reusable and visible in each of the feature definitions.
Is this possible? Is there a better way to do this?
Feature: Delay flights with down line adjustments
As a flight scheduler
I want to delay a flight and have the down line flights adjusted
for different periods
So I can more quickly update a schedule when events happen
|aircraft | flight number | dept date | dept time |
| XX1 | XX0001 | 03Mar2009 | 1000 |
| XX1 | XX0002 | 03Mar2009 | 1400 |
| XX1 | XX0003 | 03Mar2009 | 2100 |
| XX1 | XX0004 | 04Mar2009 | 1000 |
Scenario: delay flights with down line adjustments for same dept
date as delayed flight
When I delay flight XX001 by 5 mins
Then XX001 departs at 1005
Then XX002 departs at 1405
Then XX003 departs at 2105
Then XX004 departs at 1000
OR
Scenario: delay flights with down line adjustments for same dept
date as delayed flight
When I delay flight XX001 by 5 mins
Then the scheduled flight should be
|aircraft | flight number | dept date | dept time |
| XX1 | XX0001 | 03Mar2009 | 1005 |
| XX1 | XX0002 | 03Mar2009 | 1405 |
| XX1 | XX0003 | 03Mar2009 | 2105 |
| XX1 | XX0004 | 04Mar2009 | 1000 |
There are many more scenarios.
Is there a nice way to removed the duplication that is here,
especially since I will need a similar set of flights for other
scheduling change scenarios? Does anyone see a nice way to simplify
the scenarios?
Great tool by the way.
Thanks,
Wes
Have you seen this?

http://www.benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-i
n-user-stories/

Another way to remove duplication (and noise) from Cucumber steps is
the hide the details in the Ruby code that implements the step, and
write a much more general step in the feature file like this:

Given there are 3 flights departing on the same day
And the flights all leave at different times
And there is another flight leaving on the following day
When the earliest flight is delayed by 5 mins
Then the flights on the first day should all be delayed by 5
minutes
And the flight on the second day should be unaffected

These kind of steps can be clearer to read, but the trade-off is that
your underlying step code gets more complex as you start writing logic
to deliver these specific scenarios. Still, if you're clever about it,
these 'declarative' steps can still be pretty re-usable.

HTH,
Matt
Post by Williams, Wesley
Subject: [rspec-users] Reuse of Cucumber Features
+lots :)
Generally when we have problems with features its because we are
trying to
do to much at once. So in your case date entry is being complicated by
different contexts, birth and incident. One of the tennents of BDD is to
write the simplest thing you can to make you feature pass. I think
another
one should be "first of all write the simplest scenarios". So taking
one of
your examples
Scenario: Enter Valid Incident
When I fill incident correctly
I should recieve a confirmation
Then your incident step can be something like
When /^I fill incident correctly$/ do
fill_in("incident[name]", :with => ...
...
end
If you wanted to specify validation in features you could do a step like
When /^I fill incident correctly except$/ do |field|
When "I fill in incident correctly"
fill_in("incident[#{field}]", :with => ''
end
now you can create new features like
Scenario: Enter Valid Incident with no date
When I fill incident correctly except date
I should recieve an error
With a bit more trickery you could have
When I fill incident correctly except date which is xxx
Taking this approach you can build incrementally quite complex
validation
features whilst stll keeping each scenario simple and focused on one
thing.
Whether you should do this with features or put this detail
somewhere else
is another question entirely.
On another point with dates have you considered international
issues. All
the dates you've given in your example are valid (technically) there
just
not in the format you prefer. Also consider that the invalidity of
dates
might be context dependant e.g. an incident date in the future, an
appointment in the past.
HTH
Andrew
2008/12/14 Pat Maddox <pergesu at gmail.com>
Hi Steve,
I likely would only write two scenarios, one for a valid date and
one
for an invalid one. Then I would write object-level specs to
determine
what a valid date is. Extract this to a validator that you can
reuse
throughout your model.
If it's important that you write features for each potential invalid
date format (because you want to communicate them with the customer)
then I would write a feature file similar to what you show...but it
would be focused only on the date, I wouldn't mention patients or
incidents at all. Date entry seems to be an important concept in
your
application, so I would write one feature that specifies how I
expect
date entry to work, and then I can just write valid/invalid dates
for
patient and incident features. Same idea as the first paragraph,
but
using features instead of specs.
Pat
Thanks -- that gets me closer. Here's an example. Let's say I
have two
features, 'Create new patient' and 'Create new incident'. To
create a new patient you have to enter a valid birth date. To
create a
new patient you must enter a valid birth date. To create a new
incident you must enter a valid incident date. The rules for
date entry
Feature: Date entry
Scenario: Invalid month
When I fill in the date value with "13/01/2000"
I should see "Invalid date..."
Scenario: Invalid year (not 4 digits)
When I fill in the date value with "13/01/00"
I should see "Invalid date..."
Scenario: Separate with slashes (ok)
When I fill in the date value with "01/13/2000"
I should see "valid date..."
Scenario: Separate with dashes (ok)
When I fill in the date value with "01-13-2000"
I should see "valid date..."
.... etc....
Given the above, how should I write the 'create new patient' and
'create
new incident' features? I don't want to copy and paste all the
date related scenarios, but I do want to specify (and test) that
the
patient birth date and incident date fields conform to the general
date
rules. Here's how the 'create new patient' and 'create new
incident'
Feature: Create new Patient
Scenario: Enter invalid birth date
Given I fill in "birth date" with "13/01/2000"
And I fill in "patient name" with "Sam Smith"
When I press "Save"
I should see "Invalid birth date '13/01/2000'"
Scenario: Enter valid birth date, valid name
Given I fill in "birth date" with "01/13/2000"
And I fill in "patient name" with "Sam Smith"
When I press "Save"
I should see "Patient Created Successfully"
Scenario: Enter valid birth date with dashses.....
-------
Feature: Create new Incident
Scenario: Enter invalid incident date
Given I fill in "incident" with "13/01/2000"
And I fill in "supervisor" with "Sam Smith"
When I press "Save"
I should see "Invalid incident date '13/01/2000'"
Scenario: Enter valid incident date, valid supervisor
Given I fill in "incident date" with "01/13/2000"
And I fill in "supervisor" with "Sam Smith"
When I press "Save"
I should see "Incident Created Successfully"
Scenario: Enter valid incident date with dashes....
-----
Am I making sense? I want to specify the date in the features,
as there
may be extra requirements like birth dates can not be in the future
in addition to the generic date requirements. And I want to
validate
that the form checks for valid dates, displays the appropriate error
message when invalid, and uses the common rules for parsing.
But I don't
want to copy and paste those scenarios in every feature. I think
reusing steps as you mention is probably the solution but I'm
stuck on
how to word it and put it together in my case.
Steve
On Sun, Dec 14, 2008 at 8:41 AM, Matt Wynne <matt at
What's the best way to handle a requirement that shows
up as a
sub-requirement requirement in other features? For example let's
say
users can enter dates in various forms throughout my
application.
There is one set of global rules specifying the formats in which
dates may be entered, and how they are interpreted. I
put that
in one feature. In various other features, like 'Create new
patient', one can enter dates, like the patient's birth
date. I
want to do something like 'and the date entry shall follow the
normal rules' but I'm not sure how to do that in an
example
driven way, without copying and pasting from other features.
Does my question make sense? Any suggestions?
Do you know that you can call steps within steps?
http://blog.mattwynne.net/2008/11/14/dry-up-your-cucumber-steps/
Post by Williams, Wesley
Is that what you're looking for?
Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
http://rubyforge.org/mailman/listinfo/rspec-users
Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com
Zach Dennis
2009-04-09 16:47:09 UTC
Permalink
On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley
Matt,
Hmm, I think this is one way to do it.  I will need to get my customer
to think differently about defining the requirements.  They really like
the tables.
Some times table just work best. I love writing scenarios with natural
language, but I've hit many cases where the inputs and outputs are
best displayed as a table, and it's easier for the customer to gr0k,
then to read a short novel.

This kind of re-use that you seem to need sounds like a potential
feature for Cucumber. A way to utilize an external file to house a
table of data. e.g.:

Background
Given I have the following set of flights:
| foo | bar | baz |
...

Would become

Background
Given I have the following set of flights:
FromFile: flights/scheduleA

And then you'd have the flights/scheduleA house:

| foo | bar | baz |
...

Cucumber could dump in the table data it found from the file, and
print it out when running the scenarios, and it allows some sets of
sample data be re-used easily, in an understandable manner.

WDYT?
Thanks,
Wes
-----Original Message-----
Sent: Thursday, April 09, 2009 9:58 AM
To: rspec-users
Subject: Re: [rspec-users] Reuse of Cucumber Features
Post by Williams, Wesley
All,
I know this is an older post but I have a similar but different set
of scenarios I need to handle.  I have a set of flight related
scheduling features, such as delay, reschedule, and cancel, each
with multiple scenarios that have an effect on later flights in the
schedule (there are a lot of scenarios actually).  What (I think J)
I need is a set of flights that I can reuse, in a Background: given
section, by all of these features and scenarios, that is defined in
a way that is reusable and visible in each of the feature definitions.
Is this possible?  Is there a better way to do this?
Feature: Delay flights with down line adjustments
  As a flight scheduler
  I want to delay a flight and have the down line flights adjusted
for different periods
  So I can more quickly update a schedule when events happen
        |aircraft | flight number | dept date | dept time |
        | XX1      |  XX0001              | 03Mar2009 |  1000        |
        | XX1      |  XX0002              | 03Mar2009 |  1400        |
        | XX1      |  XX0003              | 03Mar2009 |  2100        |
        | XX1      |  XX0004              | 04Mar2009 | 1000         |
   Scenario:  delay flights with down line adjustments for same dept
date as delayed flight
      When I delay flight XX001 by 5 mins
      Then XX001 departs at 1005
      Then XX002 departs at 1405
      Then XX003 departs at 2105
      Then XX004 departs at 1000
OR
   Scenario:  delay flights with down line adjustments for same dept
date as delayed flight
      When I delay flight XX001 by 5 mins
      Then the scheduled flight should be
        |aircraft | flight number | dept date | dept time |
        | XX1      |  XX0001              | 03Mar2009 |  1005        |
        | XX1      |  XX0002              | 03Mar2009 |  1405        |
        | XX1      |  XX0003              | 03Mar2009 |  2105        |
        | XX1      |  XX0004              | 04Mar2009 | 1000         |
There are many more scenarios.
Is there a nice way to removed the duplication that is here,
especially since I will need a similar set of flights for other
scheduling change scenarios?  Does anyone see a nice way to simplify
the scenarios?
Great tool by the way.
Thanks,
Wes
Have you seen this?
http://www.benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-i
n-user-stories/
Another way to remove duplication (and noise) from Cucumber steps is
the hide the details in the Ruby code that implements the step, and
       Given there are 3 flights departing on the same day
       And the flights all leave at different times
       And there is another flight leaving on the following day
       When the earliest flight is delayed by 5 mins
       Then the flights on the first day should all be delayed by 5
minutes
       And the flight on the second day should be unaffected
These kind of steps can be clearer to read, but the trade-off is that
your underlying step code gets more complex as you start writing logic
to deliver these specific scenarios. Still, if you're clever about it,
these 'declarative' steps can still be pretty re-usable.
HTH,
Matt
Post by Williams, Wesley
Subject: [rspec-users] Reuse of Cucumber Features
+lots :)
Generally when we have problems with features its because we are
trying to
do to much at once. So in your case date entry is being complicated by
different contexts, birth and incident. One of the tennents of BDD is to
write the simplest thing you can to make you feature pass. I think
another
one should be "first of all write the simplest scenarios". So taking
one of
your examples
Scenario: Enter Valid Incident
  When I fill incident correctly
  I should recieve a confirmation
Then your incident step can be something like
When /^I fill incident correctly$/ do
  fill_in("incident[name]", :with => ...
  ...
end
If you wanted to specify validation in features you could do a step like
When /^I fill incident correctly except$/ do |field|
  When "I fill in incident correctly"
  fill_in("incident[#{field}]", :with => ''
end
now you can create new features like
 Scenario: Enter Valid Incident with no date
  When I fill incident correctly except date
  I should recieve an error
With a bit more trickery you could have
  When I fill incident correctly except date which is xxx
Taking this approach you can build incrementally quite complex
validation
features whilst stll keeping each scenario simple and focused on one
thing.
Whether you should do this with features or put this detail
somewhere else
is another question entirely.
On another point with dates have you considered international
issues. All
the dates you've given in your example are valid (technically) there
just
not in the format you prefer.  Also consider that the invalidity of
dates
might be context dependant e.g. an incident date in the future, an
appointment in the past.
HTH
Andrew
2008/12/14 Pat Maddox <pergesu at gmail.com>
Hi Steve,
I likely would only write two scenarios, one for a valid date and
one
for an invalid one.  Then I would write object-level specs to
determine
what a valid date is.  Extract this to a validator that you can
reuse
throughout your model.
If it's important that you write features for each potential invalid
date format (because you want to communicate them with the customer)
then I would write a feature file similar to what you show...but it
would be focused only on the date, I wouldn't mention patients or
incidents at all.  Date entry seems to be an important concept in
your
application, so I would write one feature that specifies how I
expect
date entry to work, and then I can just write valid/invalid dates
for
patient and incident features.  Same idea as the first paragraph,
but
using features instead of specs.
Pat
Thanks -- that gets me closer.  Here's an example.  Let's say I
have two
features, 'Create new patient' and 'Create new incident'.  To
create a new patient you have to enter a valid birth date.  To
create a
new patient you must enter a valid birth date.  To create a new
incident you must enter a valid incident date.  The rules for
date entry
Feature:  Date entry
  Scenario: Invalid month
  When I fill in the date value with "13/01/2000"
  I should see "Invalid date..."
  Scenario: Invalid year (not 4 digits)
  When I fill in the date value with "13/01/00"
  I should see "Invalid date..."
  Scenario: Separate with slashes (ok)
  When I fill in the date value with "01/13/2000"
  I should see "valid date..."
  Scenario: Separate with dashes (ok)
  When I fill in the date value with "01-13-2000"
  I should see "valid date..."
  .... etc....
Given the above, how should I write the 'create new patient' and
'create
new incident' features?  I don't want to copy and paste all the
date related scenarios, but I do want to specify (and test) that
the
patient birth date and incident date fields conform to the general
date
rules.  Here's how the 'create new patient' and 'create new
incident'
Feature: Create new Patient
Scenario:  Enter invalid birth date
  Given I fill in "birth date" with "13/01/2000"
  And I fill in "patient name" with "Sam Smith"
  When I press "Save"
  I should see "Invalid birth date '13/01/2000'"
Scenario:  Enter valid birth date, valid name
  Given I fill in "birth date" with "01/13/2000"
  And I fill in "patient name" with "Sam Smith"
  When I press "Save"
  I should see "Patient Created Successfully"
Scenario:  Enter valid birth date with dashses.....
-------
Feature: Create new Incident
Scenario:  Enter invalid incident date
  Given I fill in "incident" with "13/01/2000"
  And I fill in "supervisor" with "Sam Smith"
  When I press "Save"
  I should see "Invalid incident date '13/01/2000'"
Scenario:  Enter valid incident date, valid supervisor
  Given I fill in "incident date" with "01/13/2000"
  And I fill in "supervisor" with "Sam Smith"
  When I press "Save"
  I should see "Incident Created Successfully"
Scenario:  Enter valid incident date with dashes....
-----
Am I making sense?  I want to specify the date in the features,
as there
may be extra requirements like birth dates can not be in the future
in addition to the generic date requirements.  And I want to
validate
that the form checks for valid dates, displays the appropriate error
message when invalid, and uses the common rules for parsing.
But I don't
want to copy and paste those scenarios in every feature.  I think
reusing steps as you mention is probably the solution but I'm
stuck on
how to word it and put it together in my case.
Steve
On Sun, Dec 14, 2008 at 8:41 AM, Matt Wynne <matt at
        What's the best way to handle a requirement that shows
up as a
sub-requirement requirement in other features?  For example let's
say
        users can enter dates in various forms throughout my
application.
  There is one set of global rules specifying the formats in which
        dates may be entered, and how they are interpreted.  I
put that
in one feature.  In various other features, like 'Create new
        patient', one can enter dates, like the patient's birth
date.  I
want to do something like 'and the date entry shall follow the
        normal rules' but I'm not sure how to do that in an
example
driven way, without copying and pasting from other features.
        Does my question make sense?  Any suggestions?
    Do you know that you can call steps within steps?
http://blog.mattwynne.net/2008/11/14/dry-up-your-cucumber-steps/
Post by Williams, Wesley
    Is that what you're looking for?
    Matt Wynne
    http://blog.mattwynne.net
    http://www.songkick.com
    _______________________________________________
    rspec-users mailing list
    rspec-users at rubyforge.org
    http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users at rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
http://rubyforge.org/mailman/listinfo/rspec-users
Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com
_______________________________________________
rspec-users mailing list
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
http://rubyforge.org/mailman/listinfo/rspec-users
--
Zach Dennis
http://www.continuousthinking.com
http://www.mutuallyhuman.com
Zach Dennis
2009-04-09 19:30:23 UTC
Permalink
Post by Zach Dennis
On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley
Matt,
Hmm, I think this is one way to do it.  I will need to get my customer
to think differently about defining the requirements.  They really like
the tables.
Some times table just work best. I love writing scenarios with natural
language, but I've hit many cases where the inputs and outputs are
best displayed as a table, and it's easier for the customer to gr0k,
then to read a short novel.
This kind of re-use that you seem to need sounds like a potential
feature for Cucumber. A way to utilize an external file to house a
Background
    | foo | bar | baz |
    ...
Would become
Background
  FromFile: flights/scheduleA
    | foo | bar | baz |
    ...
Cucumber could dump in the table data it found from the file, and
print it out when running the scenarios, and it allows some sets of
sample data be re-used easily, in an understandable manner.
WDYT?
This is a good idea - people do this with Fit (as opposed to Fitnesse) and
go straight to a spreadsheet for the examples.
I don't see why it needs a new Cucumber feature though - you could easily
(and more flexibly) write a custom step yourself to load in the data from an
external file, right?
That's true, but why does everyone need to write their file loading
step/code? It seems like something where flexibility really doesn't
benefit anyone, unless you are doing something unique and special,
which I think is different than simply being able to store example
tables in an external file.
Matt Wynne
http://blog.mattwynne.net
http://beta.songkick.com
--
Zach Dennis
http://www.continuousthinking.com
http://www.mutuallyhuman.com
Zach Dennis
2009-04-09 19:36:49 UTC
Permalink
Post by Zach Dennis
Post by Zach Dennis
On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley
Matt,
Hmm, I think this is one way to do it.  I will need to get my customer
to think differently about defining the requirements.  They really like
the tables.
Some times table just work best. I love writing scenarios with natural
language, but I've hit many cases where the inputs and outputs are
best displayed as a table, and it's easier for the customer to gr0k,
then to read a short novel.
This kind of re-use that you seem to need sounds like a potential
feature for Cucumber. A way to utilize an external file to house a
Background
    | foo | bar | baz |
    ...
Would become
Background
  FromFile: flights/scheduleA
    | foo | bar | baz |
    ...
Cucumber could dump in the table data it found from the file, and
print it out when running the scenarios, and it allows some sets of
sample data be re-used easily, in an understandable manner.
WDYT?
This is a good idea - people do this with Fit (as opposed to Fitnesse) and
go straight to a spreadsheet for the examples.
I don't see why it needs a new Cucumber feature though - you could easily
(and more flexibly) write a custom step yourself to load in the data from an
external file, right?
That's true, but why does everyone need to write their file loading
step/code? It seems like something where flexibility really doesn't
benefit anyone, unless you are doing something unique and special,
which I think is different than simply being able to store example
tables in an external file.
One more though, how would you process your example table from a file
within a step? Would you do a giant "eval" after reading the contents?
Or would you reach into the guts of Cucumber to programmatically build
the right thing? Is there another way? I've never done it, so just
asking how you would approach this by writing your own step,
Post by Zach Dennis
Matt Wynne
http://blog.mattwynne.net
http://beta.songkick.com
--
Zach Dennis
http://www.continuousthinking.com
http://www.mutuallyhuman.com
--
Zach Dennis
http://www.continuousthinking.com
http://www.mutuallyhuman.com
Matt Wynne
2009-04-09 21:25:36 UTC
Permalink
Post by Zach Dennis
Post by Zach Dennis
Post by Zach Dennis
On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley
Post by Williams, Wesley
Matt,
Hmm, I think this is one way to do it. I will need to get my customer
to think differently about defining the requirements. They really like
the tables.
Some times table just work best. I love writing scenarios with natural
language, but I've hit many cases where the inputs and outputs are
best displayed as a table, and it's easier for the customer to gr0k,
then to read a short novel.
This kind of re-use that you seem to need sounds like a potential
feature for Cucumber. A way to utilize an external file to house a
Background
| foo | bar | baz |
...
Would become
Background
FromFile: flights/scheduleA
| foo | bar | baz |
...
Cucumber could dump in the table data it found from the file, and
print it out when running the scenarios, and it allows some sets of
sample data be re-used easily, in an understandable manner.
WDYT?
This is a good idea - people do this with Fit (as opposed to
Fitnesse) and
go straight to a spreadsheet for the examples.
I don't see why it needs a new Cucumber feature though - you could easily
(and more flexibly) write a custom step yourself to load in the data from an
external file, right?
That's true, but why does everyone need to write their file loading
step/code? It seems like something where flexibility really doesn't
benefit anyone, unless you are doing something unique and special,
which I think is different than simply being able to store example
tables in an external file.
One more though, how would you process your example table from a file
within a step? Would you do a giant "eval" after reading the contents?
Or would you reach into the guts of Cucumber to programmatically build
the right thing? Is there another way? I've never done it, so just
asking how you would approach this by writing your own step,
Not sure - I've not needed to do it yet, which is why I would balk at
generalising it into the Cucumber framework - seems a bit premature :)

I guess I would replace this:

Given I have the following set of flights:
| foo | bar | baz |

With this:

Given I have the set of flights specified in "test_data/foo.xls"

Then in that step matcher I'd open the spreadsheet, loop through the
rows and just do the same as I would with the hashes I'd normally get
from Cucumber I suppose.

Obviously you couldn't do this for scenario outline tables without
extending Cucumber, but that's another issue entirely.

Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com
Kero van Gelder
2009-04-11 11:29:59 UTC
Permalink
Post by Zach Dennis
Post by Zach Dennis
Cucumber could dump in the table data it found from the file, and
print it out when running the scenarios, and it allows some sets of
sample data be re-used easily, in an understandable manner.
If the file is used to unclutter the examples, does printing-when-running
help?
Post by Zach Dennis
This is a good idea - people do this with Fit (as opposed to Fitnesse) and
go straight to a spreadsheet for the examples.
I don't see why it needs a new Cucumber feature though - you could easily
(and more flexibly) write a custom step yourself to load in the data from an
external file, right?
That's true, but why does everyone need to write their file loading
step/code? It seems like something where flexibility really doesn't
benefit anyone, unless you are doing something unique and special,
which I think is different than simply being able to store example
tables in an external file.
Moreover, reading your own stuff is always possible in normal steps.

Nevertheless, adding something like FromFile: should give real benefits,
and I'm not sure that's the case here. Reading and writing files is
easy enough (yaml, marshal, comma separated files, ...) without special
features.

Providing data can be done with

Given("Scenario Morning rush hour") {
Given flight 1234 leaving 08:30
And flight 2345 leaving 08:32
And flight 2346 leaving 08:34
}

in a separate (step definition) file already, no?


Bye,
Kero.

___
How can I change the world if I can't even change myself?
-- Faithless, Salva Mea

Matt Wynne
2009-04-09 18:56:05 UTC
Permalink
Post by Zach Dennis
On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley
Post by Williams, Wesley
Matt,
Hmm, I think this is one way to do it. I will need to get my
customer
to think differently about defining the requirements. They really like
the tables.
Some times table just work best. I love writing scenarios with natural
language, but I've hit many cases where the inputs and outputs are
best displayed as a table, and it's easier for the customer to gr0k,
then to read a short novel.
This kind of re-use that you seem to need sounds like a potential
feature for Cucumber. A way to utilize an external file to house a
Background
| foo | bar | baz |
...
Would become
Background
FromFile: flights/scheduleA
| foo | bar | baz |
...
Cucumber could dump in the table data it found from the file, and
print it out when running the scenarios, and it allows some sets of
sample data be re-used easily, in an understandable manner.
WDYT?
This is a good idea - people do this with Fit (as opposed to Fitnesse)
and go straight to a spreadsheet for the examples.

I don't see why it needs a new Cucumber feature though - you could
easily (and more flexibly) write a custom step yourself to load in the
data from an external file, right?

Matt Wynne
http://blog.mattwynne.net
http://beta.songkick.com
Continue reading on narkive:
Loading...