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 todetermine> 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<http://rubyforge.org/mailman/listinfo/rspec-users> > writes:> > > Thanks -- that gets me closer. Here''s an example. Let''s say I havetwo> features, ''Create new patient'' and ''Create new incident''. To > > create a new patient you have to enter a valid birth date. Tocreate 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 dateentry> are the same: > > > > 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 generaldate> > rules. Here''s how the ''create new patient'' and ''create newincident''> features would look with some copy and pasting: > > > > 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, asthere> may be extra requirements like birth dates can not be in the future > > in addition to the generic date requirements. And I want tovalidate> that the form checks for valid dates, displays the appropriate error > > message when invalid, and uses the common rules for parsing. But Idon''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 stuckon> 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<http://rubyforge.org/mailman/listinfo/rspec-users> > wrote:> > > > On 13 Dec 2008, at 20:58, Steve Molitor wrote: > > > > What''s the best way to handle a requirement that shows up asa> sub-requirement requirement in other features? For example let''s say > > users can enter dates in various forms throughout myapplication.> There is one set of global rules specifying the formats in which > > dates may be entered, and how they are interpreted. I putthat> in one feature. In various other features, like ''Create new > > patient'', one can enter dates, like the patient''s birthdate. 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 >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20090408/f16f2b9b/attachment-0001.html>
On 8 Apr 2009, at 10:31, Williams, Wesley wrote:> 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, > WesHave 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> > 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 > > > > > > "Steve Molitor" <stevemolitor at gmail.com> writes: > > > > > 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 > > are the same: > > > > > > 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'' > > features would look with some copy and pasting: > > > > > > 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> wrote: > > > > > > On 13 Dec 2008, at 20:58, Steve Molitor wrote: > > > > > > 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 > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersMatt Wynne http://blog.mattwynne.net http://www.songkick.com
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 > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20090409/3058b64b/attachment-0001.html>
On Thu, Apr 9, 2009 at 3:57 AM, Matt Wynne <matt at mattwynne.net> 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20090409/f5e189d4/attachment.html>
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-bounces at rubyforge.org [mailto:rspec-users-bounces at 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20090409/d91bcbfd/attachment-0001.html>
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 at rubyforge.org [mailto:rspec-users-bounces at rubyforge.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 On 8 Apr 2009, at 10:31, Williams, Wesley wrote:> 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, > WesHave 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> > 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 > > > > > > "Steve Molitor" <stevemolitor at gmail.com> writes: > > > > > 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 > > are the same: > > > > > > 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'' > > features would look with some copy and pasting: > > > > > > 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> wrote: > > > > > > On 13 Dec 2008, at 20:58, Steve Molitor wrote: > > > > > > 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 > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersMatt 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
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 at rubyforge.org [mailto:rspec-users-bounces at rubyforge.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 at mattwynne.net> 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20090409/f799a391/attachment.html>
On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley <Wesley.Williams at sabre.com> wrote:> 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----- > From: rspec-users-bounces at rubyforge.org > [mailto:rspec-users-bounces at rubyforge.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 > > On 8 Apr 2009, at 10:31, Williams, Wesley wrote: > >> 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 > > 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 > >> >> 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 >> > >> > >> > "Steve Molitor" <stevemolitor at gmail.com> writes: >> > >> > > 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 >> > are the same: >> > > >> > > 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'' >> > features would look with some copy and pasting: >> > > >> > > 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> wrote: >> > > >> > > ? ? On 13 Dec 2008, at 20:58, Steve Molitor wrote: >> > > >> > > ? ? ? ? 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 >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > > 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 >-- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com
On 9 Apr 2009, at 17:47, Zach Dennis wrote:> On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley > <Wesley.Williams at sabre.com> wrote: >> 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?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
On Thu, Apr 9, 2009 at 2:56 PM, Matt Wynne <matt at mattwynne.net> wrote:> > On 9 Apr 2009, at 17:47, Zach Dennis wrote: > >> On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley >> <Wesley.Williams at sabre.com> wrote: >>> >>> 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? > > > 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
On Thu, Apr 9, 2009 at 3:30 PM, Zach Dennis <zach.dennis at gmail.com> wrote:> On Thu, Apr 9, 2009 at 2:56 PM, Matt Wynne <matt at mattwynne.net> wrote: >> >> On 9 Apr 2009, at 17:47, Zach Dennis wrote: >> >>> On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley >>> <Wesley.Williams at sabre.com> wrote: >>>> >>>> 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? >> >> >> 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,> > >> >> 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
On 9 Apr 2009, at 20:36, Zach Dennis wrote:> On Thu, Apr 9, 2009 at 3:30 PM, Zach Dennis <zach.dennis at gmail.com> > wrote: >> On Thu, Apr 9, 2009 at 2:56 PM, Matt Wynne <matt at mattwynne.net> >> wrote: >>> >>> On 9 Apr 2009, at 17:47, Zach Dennis wrote: >>> >>>> On Thu, Apr 9, 2009 at 9:29 AM, Williams, Wesley >>>> <Wesley.Williams at sabre.com> wrote: >>>>> >>>>> 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? >>> >>> >>> 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
> >> 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?> > 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