On Tue, Apr 21, 2009 at 11:39 AM, aslak hellesoy <aslak.hellesoy at gmail.com> wrote:> Being the author of Cucumber, some of you might be surprised that I ask this > question: > > How should I go about to implement a Cucumber feature and step definition > with the following data? > http://gist.github.com/99220 (just look at the first file for now)You left out: | Vegetarian | N | N | N |> > Imagine I''m opening a restaurant where customers are asked for their > religion. Based on what they answer, they will be presented with a tailored > menu. (Apologies in advance if I''m ignorant about what different people it). > > In Cucumber, there are several ways to put this table in a feature. It can > be part of a table in a Scenario Outline''s Examples section > (http://wiki.github.com/aslakhellesoy/cucumber/scenario-outlines), or it can > be sent to a Step as a multiline argument > (http://wiki.github.com/aslakhellesoy/cucumber/multiline-step-arguments). > > In either case, I''m not happy about the feature and step definitions I end > up with. The Scenario Outline version has annoying duplication. I have to > duplicate each meat 3 times! This makes it hard to read and edit. The > multiline step argument version isn''t much better. If a menu for a religion > is wrong I''ll only get one error, the error won''t tell me what''s wrong > (unless I explicitly craft my error messages in the step definition) and max > one failure will show (there is only one scenario). > > There should be a better way to express this kind of tests. But I''m not sure > how. Is there a smarter way with the current Cucumber? If not, how would you > *like* to express this sort of problem?How about something like this: http://gist.github.com/99235 That doesn''t require a new construct and I *think* it solves the problem (obviously I haven''t run it). An alternative would be to add a new rule or construct in which the step definition can drive things a bit more. Something like http://gist.github.com/99244 where the fact that the step def accepts 3 block args would let it consume the next three columns in the table. Not sure how crazy that would be - just an idea. WDYT?> > Cheers, > Aslak > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
aslak hellesoy wrote:> Being the author of Cucumber, some of you might be surprised that I > ask this question: > > How should I go about to implement a Cucumber feature and step > definition with the following data? > http://gist.github.com/99220 (just look at the first file for now) > > Imagine I''m opening a restaurant where customers are asked for their > religion. Based on what they answer, they will be presented with a > tailored menu. (Apologies in advance if I''m ignorant about what > different people it). > > In Cucumber, there are several ways to put this table in a feature. It > can be part of a table in a Scenario Outline''s Examples section > (http://wiki.github.com/aslakhellesoy/cucumber/scenario-outlines), or > it can be sent to a Step as a multiline argument > (http://wiki.github.com/aslakhellesoy/cucumber/multiline-step-arguments). > > In either case, I''m not happy about the feature and step definitions I > end up with. The Scenario Outline version has annoying duplication. I > have to duplicate each meat 3 times! This makes it hard to read and > edit. The multiline step argument version isn''t much better. If a menu > for a religion is wrong I''ll only get one error, the error won''t tell > me what''s wrong (unless I explicitly craft my error messages in the > step definition) and max one failure will show (there is only one > scenario). > > There should be a better way to express this kind of tests. But I''m > not sure how. Is there a smarter way with the current Cucumber? If > not, how would you *like* to express this sort of problem?I think the second way is a better way of expressing the problem, the output/run strategy is the problem. What you really want is an examples table that is embedded in a step (different from a step table, maybe by keyword?) that causes the step to be run multiple times for each of the values. So rather than using placeholders we embedded a Examples table in the step. Just my inital thoughts. I''ll knock together an example and more ideas when I get home... -- Joseph Wilk http://blog.josephwilk.net> > Cheers, > Aslak > > ------------------------------------------------------------------------ > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
On 21 Apr 2009, at 17:39, aslak hellesoy wrote:> Being the author of Cucumber, some of you might be surprised that I > ask this question: > > How should I go about to implement a Cucumber feature and step > definition with the following data? > http://gist.github.com/99220 (just look at the first file for now) > > Imagine I''m opening a restaurant where customers are asked for their > religion. Based on what they answer, they will be presented with a > tailored menu. (Apologies in advance if I''m ignorant about what > different people it). > > In Cucumber, there are several ways to put this table in a feature. > It can be part of a table in a Scenario Outline''s Examples section (http://wiki.github.com/aslakhellesoy/cucumber/scenario-outlines > ), or it can be sent to a Step as a multiline argument (http://wiki.github.com/aslakhellesoy/cucumber/multiline-step-arguments > ). > > In either case, I''m not happy about the feature and step definitions > I end up with. The Scenario Outline version has annoying > duplication. I have to duplicate each meat 3 times! This makes it > hard to read and edit. The multiline step argument version isn''t > much better. If a menu for a religion is wrong I''ll only get one > error, the error won''t tell me what''s wrong (unless I explicitly > craft my error messages in the step definition) and max one failure > will show (there is only one scenario). > > There should be a better way to express this kind of tests. But I''m > not sure how. Is there a smarter way with the current Cucumber? If > not, how would you *like* to express this sort of problem? > > Cheers, > AslakLooking at the forks of your example gist, I think I would have done it exactly the way mabes suggested. I''m not sure if I can think of a better way. Matt Wynne http://blog.mattwynne.net http://www.songkick.com
On Apr 21, 2009, at 1:57 PM, Joseph Wilk wrote:> What you really want is an examples table that is embedded in a > step (different from a step table, maybe by keyword?) that causes > the step to be run multiple times for each of the values. So rather > than using placeholders we embedded a Examples table in the step.like this? https://rspec.lighthouseapp.com/projects/16211/tickets/149-step-outline
On Tue, Apr 21, 2009 at 7:32 PM, Jonathan Linowes <jonathan at parkerhill.com> wrote:> > On Apr 21, 2009, at 1:57 PM, Joseph Wilk wrote: > >> What you really want is an examples table that is embedded in a step >> (different from a step table, maybe by keyword?) that causes the step to be >> run multiple times for each of the values. So rather than using placeholders >> we embedded a Examples table in the step. > > > like this?Not quite, I was thinking of running the whole scenario for the examples step table rather than just the step. However I really like Ben''s suggestion of a sub-table (http://gist.github.com/99255). I think it would be conceptually easier for a non-technical user to grasp than my first suggestion which makes it a big win for me. -- Joseph Wilk http://blog.josephwilk.net> https://rspec.lighthouseapp.com/projects/16211/tickets/149-step-outline > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 21 Apr 2009, at 22:13, aslak hellesoy wrote:> > > On Tue, Apr 21, 2009 at 10:20 PM, Joseph Wilk <joe at josephwilk.net> > wrote: > On Tue, Apr 21, 2009 at 7:32 PM, Jonathan Linowes > <jonathan at parkerhill.com> wrote: > > > > On Apr 21, 2009, at 1:57 PM, Joseph Wilk wrote: > > > >> What you really want is an examples table that is embedded in a > step > >> (different from a step table, maybe by keyword?) that causes the > step to be > >> run multiple times for each of the values. So rather than using > placeholders > >> we embedded a Examples table in the step. > > > > > > like this? > > Not quite, I was thinking of running the whole scenario for the > examples step table rather than just the step. > > However I really like Ben''s suggestion of a sub-table > (http://gist.github.com/99255). > > I think it would be conceptually easier for a non-technical user to > grasp than my first suggestion which makes it a big win for me. > > Thanks a lot for all the suggestions so far. I like Ben''s subtable > too. > In the example: "I should be presented a menu with <Meat Options>" I > assume the step definition would be: > > Then /I should be presented a menu with/ do |meat_hash| > # meat_hash has the following value the 2nd time (Jewish): > {''Pork''=>''N'', ''Lamb''=>''Y'', ''Veal''=>''Y''} > end > > However, having the <Meat Options> as part of the step would be > inconsistent with how the regexp matching is currently working. > > Here is an alternative: http://gist.github.com/99376 > > The idea is that we add a new kind of multiline argument in addition > to pystrings and tables: Hash. This is > done using the familiar <> delimiters as a multiline argument. > What''s inside it has no significance other than documentation. > The keys of the hash would be the same as the Examples table header > *minus* the columns that are referred in other steps. > > In essence it achieves the same as Ben''s, but relying on a > convention (removing referenced columns) rather than introducing > a new, more complex table markup. > > WDYT?I like. I also like that it''s called a ''meat hash''. Sounds tasty :) Matt Wynne http://beta.songkick.com http://blog.mattwynne.net
aslak hellesoy wrote:> > > On Tue, Apr 21, 2009 at 10:20 PM, Joseph Wilk <joe at josephwilk.net > <mailto:joe at josephwilk.net>> wrote: > > On Tue, Apr 21, 2009 at 7:32 PM, Jonathan Linowes > <jonathan at parkerhill.com <mailto:jonathan at parkerhill.com>> wrote: > > > > On Apr 21, 2009, at 1:57 PM, Joseph Wilk wrote: > > > >> What you really want is an examples table that is embedded in a > step > >> (different from a step table, maybe by keyword?) that causes > the step to be > >> run multiple times for each of the values. So rather than using > placeholders > >> we embedded a Examples table in the step. > > > > > > like this? > > Not quite, I was thinking of running the whole scenario for the > examples step table rather than just the step. > > However I really like Ben''s suggestion of a sub-table > (http://gist.github.com/99255). > > I think it would be conceptually easier for a non-technical user to > grasp than my first suggestion which makes it a big win for me. > > > Thanks a lot for all the suggestions so far. I like Ben''s subtable too. > In the example: "I should be presented a menu with <Meat Options>" I > assume the step definition would be: > > Then /I should be presented a menu with/ do |meat_hash| > # meat_hash has the following value the 2nd time (Jewish): > {''Pork''=>''N'', ''Lamb''=>''Y'', ''Veal''=>''Y''} > end > > However, having the <Meat Options> as part of the step would be > inconsistent with how the regexp matching is currently working. > > Here is an alternative: http://gist.github.com/99376 > > The idea is that we add a new kind of multiline argument in addition > to pystrings and tables: Hash. This is > done using the familiar <> delimiters as a multiline argument. What''s > inside it has no significance other than documentation. > The keys of the hash would be the same as the Examples table header > *minus* the columns that are referred in other steps. > > In essence it achieves the same as Ben''s, but relying on a convention > (removing referenced columns) rather than introducing > a new, more complex table markup. > > WDYT?Interesting.. so your meat_hash was derived from the columns of the table that were not used previously in the scenario? Meaning, that is why Religion was not part of your meat_hash. That makes sense, and.. since the scenario outline is parsed before any of the examples are ran through that convention could be maintained no matter what order the delimiters appear in the scenario. (Just thinking out loud here...) Yeah, I like it. I also agree with Matt about meat_hash. All this meat_hash talk is making me hungry... However, what if people wanted multiple hashes? Subtables would allow for this but a single hash solution would not. FWIW, here is a very contrived exampled: http://gist.github.com/99424 I agree that the sub-table is probably adding too much complexity, especially since we have a simpler alternative and no real use cases for it yet. Basically, you can ignore that last gist, I was just experimenting with contrived use cases. :) -Ben> > Aslak > > > > -- > Joseph Wilk > http://blog.josephwilk.net > > > > https://rspec.lighthouseapp.com/projects/16211/tickets/149-step-outline > > > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org <mailto:rspec-users at rubyforge.org> > > http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org <mailto: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
> > Without adding a new feature to Cucumber, I''d probably do > > > > Scenario Outline: Religious menus > > Given the customer is a "<Religion>" > > When they ask for the menu > > Then they should be presented with "<Meats>" > > > > Examples: > > | Religion | Meats | > > | Christian | Pork, Lamb, Veal | > > | Jewish | Lamb, Veal | > > | Muslim | Lamb, Veal | > > | Hindu | Lamb | > > This certainly would work, but what if we''re not dealing with booleans > (Lamb/No Lamb), but numbers? > |34,76,89| doesn''t read so well...Actually, I did just that, together with a colleague. (I removed info about what the algorithm actually computes, but the +/- indicates a threshold for that algorithm is/is not crossed; there are four algorithms not two; sorry about all that editing) Scenario Outline: measuring a series of daily weights Given patient Lara When she measures her weight as <weights> kg Then ROT algorithm result should be <ROT> And MACD algorithm result should be <MACD> ... Examples: | weights | ROT | MACD | ... | 71 72.5 72 73.3 73.6 | + | - | | 71 72 73 74 75 | - | + | ... I find this readable enough (it is much more readable than the long series of scenarios we had before). The numbers are a sequence as input for the algorithm. The sequences are concrete examples to show the differences between the outcomes of the four algorithms. What strikes me in your meat examples, is that there is a mapping from religion to types of meat that can be served (or dishes, in the end). You can test that the mapping works, why are you trying to be exhaustive in your examples? Bye, Kero.
John Goodsen wrote:> I definitely prefer the range solution over the others.I agree, it makes sense and is simple IMO.> > On Wed, Apr 22, 2009 at 2:14 AM, aslak hellesoy > <aslak.hellesoy at gmail.com <mailto:aslak.hellesoy at gmail.com>> wrote: > > > > This is actually one of the best I''ve seen so far. However it > doesn''t scale for multiple columns. (Imagine if you have 5 of them > - they easily get mixed up, or you make a spelling mistake). > > I have also taken the meat+hamburge example and tweaked a little > bit: http://gist.github.com/99620 > As you can see I''m a little sceptical of complex tables. Instead I > have invented the Range for feature writers. You specify a range > of columns you want for a column hash. (This could work along with > my example where you don''t specify a range, just any token, and > get the "rest"). > > > > -- > John Goodsen RADSoft / Better Software Faster > jgoodsen at radsoft.com <mailto:jgoodsen at radsoft.com> > Lean/Agile/XP/Scrum Coaching and Training > http://www.radsoft.com Ruby on Rails and Java Solutions > ------------------------------------------------------------------------ > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users