Tim Haines
2008-Apr-10 02:37 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
Hi there, Just want to confirm I have this right. Writing a story, assigns[:games].length.should == 30 fails for me complaining assigns[:games] is nil. It seems assigns isn''t set for story steps? I''ve changed this to response.should have_tag(".game", 30). Is this correct? Tim. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20080410/e4021bd4/attachment.html
Pat Maddox
2008-Apr-10 02:55 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Wed, Apr 9, 2008 at 7:37 PM, Tim Haines <tmhaines at gmail.com> wrote:> Hi there, > > Just want to confirm I have this right. Writing a story, > assigns[:games].length.should == 30 fails for me complaining assigns[:games] > is nil. It seems assigns isn''t set for story steps? I''ve changed this to > response.should have_tag(".game", 30). Is this correct?I would say that you shouldn''t be trying to test that sort of thing in a story. The fact that Rails assigns stuff as instance variables in views is a framework implementation detail, not externally visible behavior. Pat
David Chelimsky
2008-Apr-10 03:09 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Apr 9, 2008, at 10:37 PM, "Tim Haines" <tmhaines at gmail.com> wrote:> Hi there, > > Just want to confirm I have this right. Writing a story, assigns > [:games].length.should == 30 fails for me complaining assigns > [:games] is nil. It seems assigns isn''t set for story steps? I''ve > changed this to response.should have_tag(".game", 30). Is this > correct?Yep! The step has no access to intervals of the request.> > > Tim. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
Tim Haines
2008-Apr-10 03:20 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
Thanks Pat and David. I''m implementing paging (via will_paginate) and thought I should start with a story. I think I grok what you''re saying Pat - the stories should only be looking at "externally" visible stuff - i.e. what a real user can see or do.. That''s why you consider controller.send("current_user=",..) a bit hacky right? So to make sure I only have 30 records showing when there''s 40 in the db I should definitely be using have_tag.. Tim. On 10/04/2008, Pat Maddox <pergesu at gmail.com> wrote:> > On Wed, Apr 9, 2008 at 7:37 PM, Tim Haines <tmhaines at gmail.com> wrote: > > Hi there, > > > > Just want to confirm I have this right. Writing a story, > > assigns[:games].length.should == 30 fails for me complaining > assigns[:games] > > is nil. It seems assigns isn''t set for story steps? I''ve changed this > to > > response.should have_tag(".game", 30). Is this correct? > > > I would say that you shouldn''t be trying to test that sort of thing in > a story. The fact that Rails assigns stuff as instance variables in > views is a framework implementation detail, not externally visible > behavior. > > Pat > _______________________________________________ > 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/20080410/c338cf4a/attachment.html
Jarkko Laine
2008-Apr-10 03:55 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On 10.4.2008, at 6.20, Tim Haines wrote:> Thanks Pat and David. I''m implementing paging (via will_paginate) > and thought I should start with a story. I think I grok what you''re > saying Pat - the stories should only be looking at "externally" > visible stuff - i.e. what a real user can see or do.. That''s why > you consider controller.send("current_user=",..) a bit hacky right?Yes. Just create a given that goes through the normal logging process. You can parameterize it so that you can reuse it with different roles. //jarkko -- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2417 bytes Desc: not available Url : http://rubyforge.org/pipermail/rspec-users/attachments/20080410/2e4eb79b/attachment.bin
Ashley Moran
2008-Apr-10 06:52 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On 10 Apr 2008, at 04:20, Tim Haines wrote:> Thanks Pat and David. I''m implementing paging (via will_paginate) > and thought I should start with a story. I think I grok what you''re > saying Pat - the stories should only be looking at "externally" > visible stuff - i.e. what a real user can see or do.. That''s why > you consider controller.send("current_user=",..) a bit hacky right? > > So to make sure I only have 30 records showing when there''s 40 in > the db I should definitely be using have_tag.. > > Tim.Hi Tim I''ve just done *exactly* this. In fact, the way it works out, your view spec doesn''t have anything to do with how many items you have displayed, that''s a controller/model issue with the call to Model.paginate. In fact my view spec actually just had 3 model mocks to render, while the controller spec checked the call to Model.paginate(:per_page => 10) (is it :per_page?) and the story checked that the correct number got displayed. The view was dumb, just the way it should be. And also I had a login step like Jarkko - in fact the first step of every story was "Given a signed in admin user". Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Pat Maddox
2008-Apr-10 15:20 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Wed, Apr 9, 2008 at 8:20 PM, Tim Haines <tmhaines at gmail.com> wrote:> Thanks Pat and David. I''m implementing paging (via will_paginate) and > thought I should start with a story. I think I grok what you''re saying Pat > - the stories should only be looking at "externally" visible stuff - i.e. > what a real user can see or do.. That''s why you consider > controller.send("current_user=",..) a bit hacky right?I don''t actually think that that''s hacky. Let''s say you''ve got a story that covers logging in. Does _every single_ other story require you to cover that same basic functionality? I don''t think so. The tradeoff in this case is between purity and speed. Testing the exact path the user takes is certainly more robust. otoh, how likely is the authentication behavior going to fail? Not that likely. I think it''s reasonable to skip that part, cutting down on the number of requests that your stories make, in order to keep your story suite faster. Pat
David Chelimsky
2008-Apr-10 16:00 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Apr 10, 2008, at 11:20 AM, Pat Maddox wrote:> On Wed, Apr 9, 2008 at 8:20 PM, Tim Haines <tmhaines at gmail.com> wrote: >> Thanks Pat and David. I''m implementing paging (via will_paginate) >> and >> thought I should start with a story. I think I grok what you''re >> saying Pat >> - the stories should only be looking at "externally" visible stuff >> - i.e. >> what a real user can see or do.. That''s why you consider >> controller.send("current_user=",..) a bit hacky right? > > I don''t actually think that that''s hacky. Let''s say you''ve got a > story that covers logging in. Does _every single_ other story require > you to cover that same basic functionality? I don''t think so. The > tradeoff in this case is between purity and speed. Testing the exact > path the user takes is certainly more robust. otoh, how likely is the > authentication behavior going to fail? Not that likely. I think it''s > reasonable to skip that part, cutting down on the number of requests > that your stories make, in order to keep your story suite faster.otooh - having some scenarios logging in using a post and some by poking around under the hood creates an untested logical binding between the post and the poking. This has the same risk associated with it that raises so much concern about mocks without integration tests that don''t use mocks. I''m not saying that there should be a visible log-in step in every scenario. I would just use a request (or series of requests) instead of controller.send("current_user=",...). FWIW, David> Pat
Ashley Moran
2008-Apr-10 16:21 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On 10 Apr 2008, at 17:00, David Chelimsky wrote:> otooh - having some scenarios logging in using a post and some by > poking around under the hood creates an untested logical binding > between the post and the poking. This has the same risk associated > with it that raises so much concern about mocks without integration > tests that don''t use mocks. > > I''m not saying that there should be a visible log-in step in every > scenario. I would just use a request (or series of requests) instead > of controller.send("current_user=",...).Recently I''ve done a load of selenium-based stories and every single one had to log in, except the one that checks you can''t do anything when you are not logged in. There was no way round the login process, so I had to put it in. But there were other stories that I couldn''t do purely through the browser (eg those that needed users created and attached to organisations) because not all of the required GUI had not been built first*. For these I resorted to database access. My questions are: - is this acceptable as a bootstrapping processes (direct DB creation of data until the GUI exists) - is this acceptable in the long run, if you write a story that shows that the database changes produce the corresponding user-visible changes? Ashley * it was not an agile project -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Pat Maddox
2008-Apr-10 16:48 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Thu, Apr 10, 2008 at 9:21 AM, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> > On 10 Apr 2008, at 17:00, David Chelimsky wrote: > > > otooh - having some scenarios logging in using a post and some by > > poking around under the hood creates an untested logical binding > > between the post and the poking. This has the same risk associated > > with it that raises so much concern about mocks without integration > > tests that don''t use mocks. > > > > I''m not saying that there should be a visible log-in step in every > > scenario. I would just use a request (or series of requests) instead > > of controller.send("current_user=",...). > > Recently I''ve done a load of selenium-based stories and every single > one had to log in, except the one that checks you can''t do anything > when you are not logged in. There was no way round the login process, > so I had to put it in. But there were other stories that I couldn''t > do purely through the browser (eg those that needed users created and > attached to organisations) because not all of the required GUI had not > been built first*. For these I resorted to database access. > > My questions are: > - is this acceptable as a bootstrapping processes (direct DB creation > of data until the GUI exists)I think so. Keep in mind that not every step of every story needs to be a round-trip request. It''s even good to write some stories that don''t make requests at all! In any test, you need to control the state of the word - the test fixture. If your test requires a bit of bootstrapping in order to get there, that''s fine. The only thing that matters is that your test gives you confidence in the behavior you''re testing.> - is this acceptable in the long run, if you write a story that shows > that the database changes produce the corresponding user-visible > changes?I''m not entirely sure what you mean here. But generally if I''m testing that the user sees something, then I also want to include the step where they initiate that chain of events. Pat
David Chelimsky
2008-Apr-10 16:59 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Apr 10, 2008, at 12:48 PM, Pat Maddox wrote:> Keep in mind that not every step of every story needs to > be a round-trip request. It''s even good to write some stories that > don''t make requests at all!I definitely agree with this, however I do see a difference between accessing models directly through their API (which I do) and accessing the internals of the request cycle (which I don''t).> In any test, you need to control the state of the world - the test > fixture. If your test requires a bit of bootstrapping in order to get > there, that''s fine. The only thing that matters is that your test > gives you confidence in the behavior you''re testing.This is the ultimate bottom line. Tests are about confidence.
Ashley Moran
2008-Apr-10 21:57 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On 10 Apr 2008, at 17:59, David Chelimsky wrote:> I definitely agree with this, however I do see a difference between > accessing models directly through their API (which I do) and accessing > the internals of the request cycle (which I don''t).Ok that''s what I was doing - not interfering with anything, just using a lower-level API in the same story as a high-level API. Perhaps it wouldn''t have felt as strange if I was using a web service request instead of ORM calls? and Pat wrote:>> - is this acceptable in the long run, if you write a story that shows >> that the database changes produce the corresponding user-visible >> changes? > > I''m not entirely sure what you mean here. But generally if I''m > testing that the user sees something, then I also want to include the > step where they initiate that chain of events.Sorry wasn''t clear what I meant. I was thinking something like Given ... When I run User.create!(:foo => "bar") Then the Users page should have a row with "bar" in the "foo" column etc... Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Pat Maddox
2008-Apr-10 22:06 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Thu, Apr 10, 2008 at 2:57 PM, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> Sorry wasn''t clear what I meant. I was thinking something like > Given ... > When I run User.create!(:foo => "bar") > Then the Users page should have a row with "bar" in the "foo" columnGah, that looks hideous. When I create a user with foo="bar" is better because it doesn''t expose the implementation. Just the model concept and any relevant attributes. If possible, I like to write it in a very narrative form: Given a user named Pat And the user is 22 years old When I view the user list Then I should see the user''s name and age Your implementation of the steps can be at any level you want, for the most part. But the stories should only be in business terms. Pat
Ashley Moran
2008-Apr-10 22:30 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On 10 Apr 2008, at 23:06, Pat Maddox wrote:>> Given ... >> When I run User.create!(:foo => "bar") >> Then the Users page should have a row with "bar" in the "foo" >> column > > Gah, that looks hideous.I think you misunderstood the point - it''s supposed to look hideous :) What I meant was if you have a load of steps like Given a user named Pat And the user is 22 years old When I view the user list Then I should see the user''s name and age But say that actually, "Given a user named Pat" and "Given the user is 22 years old" are implemented as DB API calls - in this case is there merit to having a special set of stories on one side, just to verify that your low-level steps actually produce the user-facing data you expect, as if they used the GUI to create the data? I sometimes write "assumption" specs for third party code, if I am relying on behaviour I''m unsure about, just so if the lib API changes it gets flagged. I saw this as an extension of the idea, not a suggestion to send ActiveRecord method calls to a client''s marketing director!!! (I''m sure there''s some bizarre political situation somewhere where that might have an advantage though...) Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Pat Maddox
2008-Apr-10 22:38 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Thu, Apr 10, 2008 at 3:30 PM, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> > On 10 Apr 2008, at 23:06, Pat Maddox wrote: > > >> Given ... > >> When I run User.create!(:foo => "bar") > >> Then the Users page should have a row with "bar" in the "foo" > >> column > > > > Gah, that looks hideous. > > > I think you misunderstood the point - it''s supposed to look hideous :)Yes, I am thoroughly confused.> What I meant was if you have a load of steps like > > > Given a user named Pat > And the user is 22 years old > When I view the user list > Then I should see the user''s name and age > > But say that actually, "Given a user named Pat" and "Given the user > is 22 years old" are implemented as DB API calls - in this case is > there merit to having a special set of stories on one side, just to > verify that your low-level steps actually produce the user-facing data > you expect, as if they used the GUI to create the data?I don''t know what you mean by a special set of stories. In the example I gave, the Given steps would most likely be implemented as AR calls - not as separate requests. The When and Then would likely be implemented as an HTTP request and an assertion on the returned HTML. But there''s no way to tell that from the story narrative. And sometimes if the logic is complex and will take a couple iterations, I might first implement the When and Then steps as AR calls, and then as we build up the HTML pages around that infrastructure, I''d convert the step implementations to go through the web request. Are we somewhat getting on the same page by now? :)> I sometimes write "assumption" specs for third party code, if I am > relying on behaviour I''m unsure about, just so if the lib API changes > it gets flagged. I saw this as an extension of the idea, not a > suggestion to send ActiveRecord method calls to a client''s marketing > director!!! (I''m sure there''s some bizarre political situation > somewhere where that might have an advantage though...)Michael Feathers, in Working Effectively with Legacy Code, calls these characterization tests. They can certainly be very useful. Pat
Ashley Moran
2008-Apr-10 23:33 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On 10 Apr 2008, at 23:38, Pat Maddox wrote:> I don''t know what you mean by a special set of stories. In the > example I gave, the Given steps would most likely be implemented as AR > calls - not as separate requests. The When and Then would likely be > implemented as an HTTP request and an assertion on the returned HTML. > But there''s no way to tell that from the story narrative.This is the key to me. Ultimately there''s no way to prove that the story does anything until someone sees it run - at least on a real browser. Arguably even webrat etc don''t demonstrably prove that the app works. That was my feeling with using DB calls, they aren''t demonstrable enough. I had a handover meeting with my client today, and for the functionality I built he was most interested in seeing the stories, first in text and then actually run. And actually it was satisfying for me to run them, knowing there''s no disputing something you can see running in front of your eyes. But I felt the need to apologise for steps that "cheated", such as those that inspected the database for model states, instead of pages for content keywords.> And > sometimes if the logic is complex and will take a couple iterations, I > might first implement the When and Then steps as AR calls, and then as > we build up the HTML pages around that infrastructure, I''d convert the > step implementations to go through the web request. > > Are we somewhat getting on the same page by now? :)Uhuh :D That''s what I meant by "bootstrapping" - writing DB API steps to get yourself going. Then you have two choices - "upgrade" them to "real" steps like you say above, or write "characterization tests" like you say below. I was just wondering what people thought of the two opinions. Sorry for taking so long to get my point across... typing posts at 100mph in between coding, and expecting everyone to read my mind...> Michael Feathers, in Working Effectively with Legacy Code, calls these > characterization tests. They can certainly be very useful.Thanks for the book recommendation, I''ve forwarded it to some people I know that haven''t had the luxury of using Ruby full time. Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Rick DeNatale
2008-Apr-11 02:14 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Thu, Apr 10, 2008 at 6:38 PM, Pat Maddox <pergesu at gmail.com> wrote:> On Thu, Apr 10, 2008 at 3:30 PM, Ashley Moran> > But say that actually, "Given a user named Pat" and "Given the user > > is 22 years old" are implemented as DB API calls - in this case is > > there merit to having a special set of stories on one side, just to > > verify that your low-level steps actually produce the user-facing data > > you expect, as if they used the GUI to create the data? > > I don''t know what you mean by a special set of stories. In the > example I gave, the Given steps would most likely be implemented as AR > calls - not as separate requests. The When and Then would likely be > implemented as an HTTP request and an assertion on the returned HTML. > But there''s no way to tell that from the story narrative. And > sometimes if the logic is complex and will take a couple iterations, I > might first implement the When and Then steps as AR calls, and then as > we build up the HTML pages around that infrastructure, I''d convert the > step implementations to go through the web request.I''m working on a project right now in which the business rules and logic took some time to discover via iteration and experimentation. The UI work started later and overlapped somewhat. I started by writing a plain text story, and steps which worked at the AR level. I''ve done the UI work mostly with specs and not stories. I''m now at the point of converting the steps into the equivalent of a ''traditional'' Rails integration test. BUT I''m thinking that I might just write a whole new xxx_steps.rb file which would run the same story but at the real user interaction level, and keep the model level steps also. I still haven''t convinced myself one way or the other. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
Kamal Fariz
2008-Apr-11 02:16 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
> When I create a user with foo="bar" > > is better because it doesn''t expose the implementation. Just the > model concept and any relevant attributes.I hide model details from Stories by using webrat and form field labels. When I create a user with Username: kamal, Password: test And click submit Seems safer that way as the views get tested at the same time. Regards, kamal
Tim Haines
2008-Apr-11 02:51 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
I read about webrat and stories 30 mins ago - http://www.benmabey.com/2008/02/04/rspec-plain-text-stories-webrat-chunky-bacon/- good article. Tim. On 11/04/2008, Kamal Fariz <kamal.fariz at gmail.com> wrote:> > > When I create a user with foo="bar" > > > > is better because it doesn''t expose the implementation. Just the > > model concept and any relevant attributes. > > > I hide model details from Stories by using webrat and form field labels. > > When I create a user with Username: kamal, Password: test > And click submit > > Seems safer that way as the views get tested at the same time. > > > Regards, > > kamal > > _______________________________________________ > 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/20080411/6602a5fe/attachment.html
Ashley Moran
2008-Apr-11 08:44 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On 11 Apr 2008, at 03:14, Rick DeNatale wrote:> I''m thinking that I might just write a whole new xxx_steps.rb file > which would run the same story but at the real user interaction level, > and keep the model level steps also. I still haven''t convinced myself > one way or the other.Wow, I had never thought of this. Could you really write a story that could be executed in two different environments based on the steps file that got loaded? Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
David Chelimsky
2008-Apr-11 12:15 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Apr 11, 2008, at 4:44 AM, Ashley Moran <ashley.moran at patchspace.co.uk> wrote:> > On 11 Apr 2008, at 03:14, Rick DeNatale wrote: > >> I''m thinking that I might just write a whole new xxx_steps.rb file >> which would run the same story but at the real user interaction >> level, >> and keep the model level steps also. I still haven''t convinced >> myself >> one way or the other. > > Wow, I had never thought of this. Could you really write a story that > could be executed in two different environments based on the steps > file that got loaded?Absolutely. That is, in fact, one benefit of plain text stories that we don''t have with ruby stories ... Yet.> > > 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
David Chelimsky
2008-Apr-11 14:18 UTC
[rspec-users] Stories - Use view matchers rather than assigns[].should?
On Apr 11, 2008, at 8:15 AM, David Chelimsky wrote:> On Apr 11, 2008, at 4:44 AM, Ashley Moran <ashley.moran at patchspace.co.uk > > wrote: > >> >> On 11 Apr 2008, at 03:14, Rick DeNatale wrote: >> >>> I''m thinking that I might just write a whole new xxx_steps.rb file >>> which would run the same story but at the real user interaction >>> level, >>> and keep the model level steps also. I still haven''t convinced >>> myself >>> one way or the other. >> >> Wow, I had never thought of this. Could you really write a story >> that >> could be executed in two different environments based on the steps >> file that got loaded? > > Absolutely. That is, in fact, one benefit of plain text stories that > we don''t have with ruby stories ... Yet.This is also a motivating factor in my own choice to keep the steps worded at high levels of abstraction. For example: Given I am filling in my profile When I enter nothing for E-Mail Address And I submit my info Then I should receive an error message telling me that E-Mail Address is required This scenario does not say "page" or "screen." It could run against a web system, desktop, command line, or even a batch system, though that might be a bit of a stretch. Of course, there are going to be cases when more granularity is required. If there is a requirement for a very specific user experience, something ajaxy for example, but these should be separated out as UI specific stories. Cheers, David -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20080411/a647381d/attachment.html