Hi I just wondered what the plan was for multi-line steps. Is anyone working on it? I''ve just come across a real use for it (including small text files in the story). Cheers Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Hi Ashley, What''s your use case? I''m curious... Tim. On 09/04/2008, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> > Hi > > I just wondered what the plan was for multi-line steps. Is anyone > working on it? I''ve just come across a real use for it (including > small text files in the story). > > Cheers > Ashley > > -- > http://www.patchspace.co.uk/ > http://aviewfromafar.net/ > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20080409/b98f4c92/attachment-0001.html
On Wed, Apr 9, 2008 at 12:31 PM, Tim Haines <tmhaines at gmail.com> wrote:> Hi Ashley, > > What''s your use case? I''m curious... > > Tim. > >I''m working on a Treetop (http://treetop.rubyforge.org/) implementation of the Story parser. Please file any suggestions for improvements to the story format to lighthouse and tag with story_grammar Aslak> > On 09/04/2008, Ashley Moran <ashley.moran at patchspace.co.uk> wrote: > > Hi > > > > I just wondered what the plan was for multi-line steps. Is anyone > > working on it? I''ve just come across a real use for it (including > > small text files in the story). > > > > Cheers > > Ashley > > > > -- > > http://www.patchspace.co.uk/ > > http://aviewfromafar.net/ > > > > > > > > _______________________________________________ > > 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 >
David Chelimsky
2008-Apr-09 12:41 UTC
[rspec-users] External Dependencies (was Multi-line steps)
On Apr 9, 2008, at 8:13 AM, aslak hellesoy wrote:> I''m working on a Treetop (http://treetop.rubyforge.org/) > implementation of the Story parser.Hey Aslak, while I love the idea of exploiting treetop for this, this would be our first external dependency for end users. That was one of the reasons I didn''t use treetop in the first place - it had just been released and Brian suggested exporing it when I was working on Plain Text Stories. Personally, I''m in support of external dependencies, especially in light of recent improvements to Rubygems that make it even easier for a gem to manage its own dependencies. But thus far we''ve had an only slightly-less-than-official policy of no external dependencies. Has your thinking on this issue shifted as well?
On Wed, Apr 9, 2008 at 6:03 AM, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> Hi > > I just wondered what the plan was for multi-line steps. Is anyone > working on it? I''ve just come across a real use for it (including > small text files in the story).It'' might be a little clunky, but I''ve recently done something like this in a story involving uploading a csv file .... When Fred creates a csv file And the csv file has a record with "first_name", "last_name" And the csv file has a record with "Bilbo", "Baggins" And the csv file has a record with "Arwen", "Evenstar" And Fred uploads the csv file The step for the first line creates an empty string object, and the next three append to it. The final step does whatever is needed to turn the string into a TestUploadFile or whatever is needed. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
aslak hellesoy
2008-Apr-09 13:11 UTC
[rspec-users] External Dependencies (was Multi-line steps)
On Wed, Apr 9, 2008 at 2:41 PM, David Chelimsky <dchelimsky at gmail.com> wrote:> On Apr 9, 2008, at 8:13 AM, aslak hellesoy wrote: > > > I''m working on a Treetop (http://treetop.rubyforge.org/) > > implementation of the Story parser. > > Hey Aslak, while I love the idea of exploiting treetop for this, this > would be our first external dependency for end users. That was one of > the reasons I didn''t use treetop in the first place - it had just been > released and Brian suggested exporing it when I was working on Plain > Text Stories. > > Personally, I''m in support of external dependencies, especially in > light of recent improvements to Rubygems that make it even easier for > a gem to manage its own dependencies. But thus far we''ve had an only > slightly-less-than-official policy of no external dependencies. Has > your thinking on this issue shifted as well?I realize it will introduce a dependency on treetop, but now that rubygems are ubiquotous and has largely improved with 1.1.0 I think it''s ok. It would only be needed for stories. A treetop based parser has several benefits: * Much simpler codebase * Much better error messages for users. Line numbers and conflict detection. * Easier integration with other tools (including rspec core) * Simpler setup for story running (I have a vague plan for that in my head). I haven''t committed the code yet - for now it will live in a separate repo on GitHub. Here is a teaser for the grammar: grammar Story rule story header narrative scenario* end rule header ''Story: '' sentence_line end rule narrative ''As a'' sentence_line end rule scenario ''Scenario: '' sentence_line step* end rule step # The various step rules are generated dynamically ''Given '' (step_1 / step_2) end # Dynamically generated rule rule step_1 ''I am '' word '' and '' word end # Dynamically generated rule rule step_2 ''I was '' word '' and '' word end rule word ([\w])* end rule sentence_line (!eol .)* eol end rule eol "\n" / eof end rule eof !. end end Basically, each run will be based on a core grammar which is extended by the user, creating extra rules for each parameterised step. The treetop based parser would create the grammar dynamically, compile it in-memory and use it to parse plain text stories. My first benchmarks are pretty good - 0.03 secs to parse/compile the grammar and less than 0.0001 secs to parse a simple story. This is fun! Aslak> _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On Wed, Apr 9, 2008 at 2:59 PM, Rick DeNatale <rick.denatale at gmail.com> wrote:> On Wed, Apr 9, 2008 at 6:03 AM, Ashley Moran > > <ashley.moran at patchspace.co.uk> wrote: > > > Hi > > > > I just wondered what the plan was for multi-line steps. Is anyone > > working on it? I''ve just come across a real use for it (including > > small text files in the story). > > It'' might be a little clunky, but I''ve recently done something like > this in a story involving uploading a csv file > > .... > When Fred creates a csv file > And the csv file has a record with "first_name", "last_name" > And the csv file has a record with "Bilbo", "Baggins" > And the csv file has a record with "Arwen", "Evenstar" > And Fred uploads the csv file >Just a style comment: I usually strive for a single When (in this case Fred uploads the csv file). The other ones are Givens.> The step for the first line creates an empty string object, and the > next three append to it. The final step does whatever is needed to > turn the string into a TestUploadFile or whatever is needed. >Still interested in seeing how a multiline step would look. I''m also interested in how we can do more FIT-like things using tables. But maybe that belongs in a different tool... Aslak> -- > Rick DeNatale > > My blog on Ruby > http://talklikeaduck.denhaven2.com/ > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On Wed, Apr 9, 2008 at 9:14 AM, aslak hellesoy <aslak.hellesoy at gmail.com> wrote:> I''m also interested in how we can do more FIT-like things using > tables. But maybe that belongs in a different tool...Like, uh .... FIT? I''ve been thinking of resurrecting the Ruby FIT project which seems to have no commits since 2006. I can definitely see an RSpec-FIT bridge (separate library) that allows you to run FIT pages and RSpec scenarios with unified reporting. Of course, this will have to wait for RSpec 1.2, the book, and maybe a vacation or two ... Cheers, David
On Wed, Apr 9, 2008 at 3:33 PM, David Chelimsky <dchelimsky at gmail.com> wrote:> On Wed, Apr 9, 2008 at 9:14 AM, aslak hellesoy <aslak.hellesoy at gmail.com> wrote: > > I''m also interested in how we can do more FIT-like things using > > tables. But maybe that belongs in a different tool... > > Like, uh .... FIT?Exactly. I have tried RubyFIT - it''s OK, but dead as you mentioned. It would be nice with a more recent RubyFIT implementation that leverages all the goodies in the RSpec code (and community). Aslak> > I''ve been thinking of resurrecting the Ruby FIT project which seems to > have no commits since 2006. I can definitely see an RSpec-FIT bridge > (separate library) that allows you to run FIT pages and RSpec > scenarios with unified reporting. > > Of course, this will have to wait for RSpec 1.2, the book, and maybe a > vacation or two ... > > Cheers, > David > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On Wed, Apr 9, 2008 at 9:14 AM, aslak hellesoy <aslak.hellesoy at gmail.com> wrote:> On Wed, Apr 9, 2008 at 2:59 PM, Rick DeNatale <rick.denatale at gmail.com> wrote: > > On Wed, Apr 9, 2008 at 6:03 AM, Ashley Moran > > > > <ashley.moran at patchspace.co.uk> wrote: > > > > > Hi > > > > > > I just wondered what the plan was for multi-line steps. Is anyone > > > working on it? I''ve just come across a real use for it (including > > > small text files in the story). > > > > It'' might be a little clunky, but I''ve recently done something like > > this in a story involving uploading a csv file > > > > .... > > When Fred creates a csv file > > And the csv file has a record with "first_name", "last_name" > > And the csv file has a record with "Bilbo", "Baggins" > > And the csv file has a record with "Arwen", "Evenstar" > > And Fred uploads the csv file > > > > Just a style comment: I usually strive for a single When (in this case > > Fred uploads the csv file). > The other ones are Givens.Yes, that''s how I actually wrote it, just checked. I was working from memory from a machine which didn''t have the actual code, and with too little coffee in my system for that hour of the morning to boot! <G> -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
On 9 Apr 2008, at 11:31, Tim Haines wrote:> Hi Ashley, > > What''s your use case? I''m curious... > > Tim.Hi Tim I''ve finally started writing a tool I''ve wanted for ages: a REAL database migration system, that works on a patch system with dependency tracking (like darcs), not a borked^H^H^H^H^H^H linear scheme like AR Migrations. So I started writing the story and I wanted to write something this: Scenario: two steps depend on third Given a file "db/migrate/a.migrate.rb": migration "migration A" do |m| m.depends_on "migration X" end And a file "db/migrate/b.migrate.rb": migration "migration B" do m.depends_on "migration X" end And a file "db/migrate/x.migrate.rb": migration "migration X" do end When ... In the end I did it like the way Rick''s mate Fred builds CSVs, but breaking down a single step can be cumbersome. Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
On 9 Apr 2008, at 14:14, aslak hellesoy wrote:> Just a style comment: I usually strive for a single When (in this case > Fred uploads the csv file). > The other ones are Givens.Hmm, I''ve written a lot of Selenium stories lately, and they look like this: Given ... When the user visits /my_page And clicks on "Edit" And types "Cow" in the favourite_animal text field And clicks the save button Then ... Is that bad? Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
On 4/9/08, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> > On 9 Apr 2008, at 14:14, aslak hellesoy wrote: > > > Just a style comment: I usually strive for a single When (in this case > > Fred uploads the csv file). > > The other ones are Givens. > > Hmm, I''ve written a lot of Selenium stories lately, and they look like > this: > > Given ... > > When the user visits /my_page > And clicks on "Edit" > And types "Cow" in the favourite_animal text field > And clicks the save button > > Then ... > > Is that bad?Not bad, but perhaps misleading. Given is used to express preconditions, wheras When is for an action. Her you are expressing preconditions, even if those preconditions are action-based instead of state-based (e.g. the known state of the work is that the user has performed these actions) Does that make any sense? Pat
On 9 Apr 2008, at 22:04, Pat Maddox wrote:> Not bad, but perhaps misleading. Given is used to express > preconditions, wheras When is for an action. Her you are expressing > preconditions, even if those preconditions are action-based instead of > state-based (e.g. the known state of the work is that the user has > performed these actions) > > Does that make any sense?I knew you would say that :) It just seems unclear, I mean you could turn When the user vists /my_page And clicks the do_something button into either Given the user is on /my_page When he clicks the do_something button or When the user clicks the do_something button on /my_page The first solution looks better, but I guess it depends how atomic you want to make the steps. You could always write this, if you were so inclined... Given the user has a browser And they have typed "http://www.mysite.com" into the address bar And pressed enter And moved the mouse over the do_something button And pressed the mouse button ... Wouldn''t wanna write that as one step... Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
On Apr 9, 2008, at 5:04 PM, Pat Maddox wrote:> On 4/9/08, Ashley Moran <ashley.moran at patchspace.co.uk> wrote: >> >> On 9 Apr 2008, at 14:14, aslak hellesoy wrote: >> >>> Just a style comment: I usually strive for a single When (in this >>> case >>> Fred uploads the csv file). >>> The other ones are Givens. >> >> Hmm, I''ve written a lot of Selenium stories lately, and they look >> like >> this: >> >> Given ... >> >> When the user visits /my_page >> And clicks on "Edit" >> And types "Cow" in the favourite_animal text field >> And clicks the save button >> >> Then ... >> >> Is that bad? > > Not bad, but perhaps misleading. Given is used to express > preconditions, wheras When is for an action. Her you are expressing > preconditions, even if those preconditions are action-based instead of > state-based (e.g. the known state of the work is that the user has > performed these actions) > > Does that make any sense? > > PatThis actually sounds more confusing to me when viewed in the context of my own stories, and it seems similar to what''s going on here. I write a lot about the user''s interaction with the site and what should happen, so I have a lot of stories that look like: Given database is in this state When user does this stuff in browser Then database should be in this new state If the point of the Story is to see what happens when a user clicks buttons while the app is in a certain state, then moving those to a "Given" means you have no more actions left. If all the action happened in the "Given", then there won''t be a When statement at all. Glenn
On 10 Apr 2008, at 18:28, Glenn Ford wrote:> Given database is in this state > When user does this stuff in browser > Then database should be in this new stateI like the way you phrased this Glenn. Maybe the distinction is that Given is everything outside the control of the user, or, if the user set up the Given themself, all the stuff they *completed* in a previous session (no transition states). What erked me about Pat''s earlier suggestion was it felt like half the stuff the user did was in Given, which left the end of the Given section describing a state that a user could not find the system in. I don''t see that Given or Then has to be restricted to the database though - it could refer to the pre- or post-When state of an external web services, the contents in the browser, files read or written. Anything really. Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
On Thu, Apr 10, 2008 at 7:28 PM, Glenn Ford <glenn at aldenta.com> wrote:> > On Apr 9, 2008, at 5:04 PM, Pat Maddox wrote: > > > On 4/9/08, Ashley Moran <ashley.moran at patchspace.co.uk> wrote: > >> > >> On 9 Apr 2008, at 14:14, aslak hellesoy wrote: > >> > >>> Just a style comment: I usually strive for a single When (in this > >>> case > >>> Fred uploads the csv file). > >>> The other ones are Givens. > >> > >> Hmm, I''ve written a lot of Selenium stories lately, and they look > >> like > >> this: > >> > >> Given ... > >> > >> When the user visits /my_page > >> And clicks on "Edit" > >> And types "Cow" in the favourite_animal text field > >> And clicks the save button > >> > >> Then ... > >> > >> Is that bad? > > > > Not bad, but perhaps misleading. Given is used to express > > preconditions, wheras When is for an action. Her you are expressing > > preconditions, even if those preconditions are action-based instead of > > state-based (e.g. the known state of the work is that the user has > > performed these actions) > > > > Does that make any sense? > > > > Pat > > This actually sounds more confusing to me when viewed in the context > of my own stories, and it seems similar to what''s going on here. I > write a lot about the user''s interaction with the site and what should > happen, so I have a lot of stories that look like: > > Given database is in this state > When user does this stuff in browser > Then database should be in this new state >This is a very "technical" way to express a scenario. It wouldn''t make much sense to a typical domain expert (unless they know about databases). I generally try to write scenarios using the domain language, focussing on outcomes for users (not computers). Example: Given the customers joe, paul and lisa are registered users When a user signs up as lisa Then the user should be informed that the name is taken And the user lisa should not be able to log in Aslak> If the point of the Story is to see what happens when a user clicks > buttons while the app is in a certain state, then moving those to a > "Given" means you have no more actions left. If all the action > happened in the "Given", then there won''t be a When statement at all. > > Glenn > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On Thu, Apr 10, 2008 at 5:25 PM, aslak hellesoy <aslak.hellesoy at gmail.com> wrote:> > This is a very "technical" way to express a scenario. It wouldn''t make > much sense to a typical domain expert (unless they know about > databases). > I generally try to write scenarios using the domain language, > focussing on outcomes for users (not computers). Example: > > Given the customers joe, paul and lisa are registered users > When a user signs up as lisa > Then the user should be informed that the name is taken > And the user lisa should not be able to log inI''m not sure which of the two lisas I should feel sorry for. <G> -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
>> This actually sounds more confusing to me when viewed in the context >> of my own stories, and it seems similar to what''s going on here. I >> write a lot about the user''s interaction with the site and what >> should >> happen, so I have a lot of stories that look like: >> >> Given database is in this state >> When user does this stuff in browser >> Then database should be in this new state >> > > This is a very "technical" way to express a scenario. It wouldn''t make > much sense to a typical domain expert (unless they know about > databases). > I generally try to write scenarios using the domain language, > focussing on outcomes for users (not computers). Example: > > Given the customers joe, paul and lisa are registered users > When a user signs up as lisa > Then the user should be informed that the name is taken > And the user lisa should not be able to log in > > AslakYou''re right, and I don''t literally write them in this format. But if you interpret the business logic that''s in them into what they actually mean technically, it really just is the state of the database and I guess we can also add the session/cookies/flash. Even in the example you just gave, you express in your "Given" that in the Users table of your db there are 3 entries. For your "When" there is a user interacting with the web app. "Then" shows that an error is in the response. You could also check to ensure that the number of Users in the database did not change. This, I know, is more of a technical way to look at it, but I''ve personally found use for this when realizing a tricky view was passing bad data to a controller and my Story caught it. It was getting the right flash message in the end... but there were too many entities being created in the db. I didn''t catch this until the Story spec so I still think there''s a use for this! You could even break apart "And the user..." into: When a user tries to log in as lisa Then the user should be informed that no such customer exists Because really the current statement includes multiple steps. Going to the login page, filling out the data, submitting it, and then checking the response/redirect. If there were an error in your "Then the user $lisa should not be able to log in" step, it would be untested and it''s actually not quite trivial since it''s not a single step. That''s probably more nit-picky since I''m sure the step would be used in many other places to give you added confidence, but since you mentioned "When" is for actions and your example "And Then" has an action, I still think it''s interesting to look at :) Glenn
On Thu, Apr 10, 2008 at 6:10 PM, Glenn Ford <glenn at aldenta.com> wrote: Quoting Aslak> > Given the customers joe, paul and lisa are registered users > > When a user signs up as lisa > > Then the user should be informed that the name is taken > > And the user lisa should not be able to log in> You''re right, and I don''t literally write them in this format. But if > you interpret the business logic that''s in them into what they > actually mean technically, it really just is the state of the database > and I guess we can also add the session/cookies/flash. > > Even in the example you just gave, you express in your "Given" that in > the Users table of your db there are 3 entries. For your "When" there > is a user interacting with the web app. "Then" shows that an error is > in the response.Actually, that there are three users with specific user names.> You could also check to ensure that the number of Users in the > database did not change. This, I know, is more of a technical way to > look at it, but I''ve personally found use for this when realizing a > tricky view was passing bad data to a controller and my Story caught > it. It was getting the right flash message in the end... but there > were too many entities being created in the db. I didn''t catch this > until the Story spec so I still think there''s a use for this! > > You could even break apart "And the user..." into: > > When a user tries to log in as lisa > Then the user should be informed that no such customer existsWhich if you step back and look at the whole story is problematic, because, as I tried to point out, perhaps a bit too tongue in cheek, ''Lisa'' here is ambiguous. There is one Lisa who is already a registered user, and a second one who tries to use the name which is already taken. And I wouldn''t think that most reasonable systems would disable Lisa1''s account because some Lisa2 tried and failed to use the same name.> Because really the current statement includes multiple steps. Going > to the login page, filling out the data, submitting it, and then > checking the response/redirect. If there were an error in your "Then > the user $lisa should not be able to log in" step, it would be > untested and it''s actually not quite trivial since it''s not a single > step. That''s probably more nit-picky since I''m sure the step would be > used in many other places to give you added confidence, but since you > mentioned "When" is for actions and your example "And Then" has an > action, I still think it''s interesting to look at :)And to make the distinction between Given''s, When''s and Then''s fuzzier, there''s GivenScenario, which effectively converts all of a scenario''s Givens, When''s and I guess Then''s into a Given for a subsequent scenario. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
On 11 Apr 2008, at 03:03, Rick DeNatale wrote:> And I wouldn''t think that most reasonable systems would disable > Lisa1''s account because some Lisa2 tried and failed to use the same > name.Somebody, somewhere has built a system that does this. You know it. -- http://www.patchspace.co.uk/ http://aviewfromafar.net/