Matthijs Langenberg
2008-Mar-04 13:13 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
I really would like to know how people are using the Story and Example runner to write their software.It would be great to get some direction on it, because I think I''m missing some points. Taking the outside-in approach in thought: At first we write a high-level customer-facing story, this story fails. Then we start using mocks at object level to use them as a design tool, and so we implement the different layers of the system. After implementing the inner layer, the story should pass. When that happens we could remove the mocks and replace it with calls to the real code, making the suite less brittle (except for calls to external services/databases/file systems). So if the story passes all acceptance tests, why is there a need for examples at a lower level? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20080304/84d32aee/attachment.html
Chris Parsons
2008-Mar-04 13:43 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
On 4 Mar 2008, at 13:13, Matthijs Langenberg wrote:> Taking the outside-in approach in thought: > > At first we write a high-level customer-facing story, this story > fails. > Then we start using mocks at object level to use them as a design > tool, > and so we implement the different layers of the system. > After implementing the inner layer, the story should pass. > When that happens we could remove the mocks and replace it with > calls to the real code, making the suite less brittle (except for > calls to external services/databases/file systems).Don''t use mocks at the story level. IMHO stories should always be using the full stack. This includes your database, but you might be permitted to exclude external services such as credit card billing systems. However, if you can set up a sandbox to test against (such as the Paypal sandbox), all to the good. We proceed based on two principles: A failure in a story means you change specs not code. A failure in a spec means you change the code. This is how we do it (assuming a rails application): 1. Write customer story, all steps are pending: Scenario: Viewing the front page When I view the front page Then I see the text ''welcome to the app'' 2. Write the first step in the story: When "I view the front page" do get "/" end This then fails, as I don''t have a front page yet! 3. Pay attention to the error given by the story, and fix that *by writing a spec*. In this case it''ll be complaining that the controller doesn''t exist. At this point I drop down to the specs as a failing story means we need a spec: describe MainController do end 4. Make your specs pass. ''rake spec'' then fails, as MainController doesn''t exist. In this case, I add a controller and a route (by hand, none of that scaffold business): class MainController < ApplicationController end 5. Run the story again if you need to, and use that as a guide to write more specs. Repeat steps 4 and 5. To continue the example - in this case it''ll probably complain about no index action: describe MainController do it "should handle an index action" do get :index end end and then, to fix the spec: class MainController < ApplicationController def index end end Then it''ll most likely complain about not having an index.html.erb. Because controller specs don''t render the page, you''ll need an an index.html.erb_spec.rb to test the view properly. And so on. Sound like a lot of work, but given practice you can zip through these steps very quickly. You also get a free ''focusing tool'' (lose sight of where you are? just run the story test and write more specs). Hope this is helpful. Maybe I should write up an extended example as a blog post, including mocking etc, as it seems to come up a lot. Thanks Chris PS: Excuse the spelling/coding mistakes in the (untested) code :) Corrections and comments as to the methodology here most welcome. -- Chris Parsons Managing Director Eden Development (UK) Ltd chris at edendevelopment.co.uk www.edendevelopment.co.uk 0845 0097 094 po box 425, winchester, so23 0wy, uk Map: http://pininthemap.com/edendevelopment Tried Pin in the Map? Mark a map location, add text, send to friends. http://pininthemap.com This electronic message and all contents contain information from the sender which may be privileged, confidential or otherwise protected from disclosure. The information is intended to be for the addressee(s) only. If you are not an addressee, any copying, disclosure, distribution or use of the contents of this message is prohibited. If you have received this electronic message in error, please notify the sender by reply e-mail and destroy the original message and all copies. The sender does not accept liability for any errors or omissions.
David Chelimsky
2008-Mar-04 14:13 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
On Tue, Mar 4, 2008 at 7:13 AM, Matthijs Langenberg <mlangenberg at gmail.com> wrote:> I really would like to know how people are using the Story and Example > runner to write their software. > It would be great to get some direction on it, because I think I''m missing > some points. > > Taking the outside-in approach in thought: > > At first we write a high-level customer-facing story, this story fails. > Then we start using mocks at object level to use them as a design tool, > and so we implement the different layers of the system. > After implementing the inner layer, the story should pass. > When that happens we could remove the mocks and replace it with calls to the > real code,I do this sometimes - removing the mocks - as long as the objects are trivial to set up and they don''t have dependencies that I don''t want to expose. There''s no one way to do this, and I''ll sometimes remove mocks and reintroduce them over the life of a project.> making the suite less brittleWhat brittle means is a bit subjective here. Just a lengthy conversation about this in irc last night. The guy with whom I was chatting prefers to not use mocks because he''d rather see a change cause a bunch of lower level examples to fail than stories. From what I can tell, he doesn''t like to use mocks even temporarily, in process. His approach has the benefit that you learn about side effects of your changes faster, and the cost that it means you sometimes have more "red bar" to wade through while you get things right. My approach has the benefit that you can address side effects of your changes with a green bar helping you know that the smaller bits (objects and methods) are functioning, and the cost that you sometimes don''t learn about side effects until you run your stories (or integration suite). Neither solution is perfect. You just have to pick your poison.> (except for calls to external > services/databases/file systems).This is a funny thing about ruby, specifically rails. One of the hallmarks of OO is a high level of decoupling - especially decoupling your code from 3rd party code through adapters. There are a couple of reasons for this. One is that having an adapter lets you write exactly the code that you want to write throughout most of your system, rather than being subject to the naming conventions of the 3rd party library that might clash with those in your system or even with your domain. The other is that if you decide to switch to a different library, you''re pretty well hosed unless you have adapters. If you look at the competitors to ActiveRecord, like Og and Datamapper, they are all VERY similar syntactically. Why? Two reasons I think. One is that AR got a lot of things right from a domain perspective. The other is that calls to AR internals have leaked out to a lot of controllers and even views: Person.find(:all, :conditions => [''active = ?'', true]) In spite of guidelines all over the web that say that this should be wrapped in a #find_active method in the model, these sorts of things pop up all over the place anyhow.> So if the story passes all acceptance tests, why is there a need for > examples at a lower level?So that you can get things working one step at a time, and then change things as needed one step at a time, with green bars keeping you sane, stress free, and even happy all the way through. HTH, David
David Chelimsky
2008-Mar-04 14:17 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
On Tue, Mar 4, 2008 at 8:13 AM, David Chelimsky <dchelimsky at gmail.com> wrote:> On Tue, Mar 4, 2008 at 7:13 AM, Matthijs Langenberg > <mlangenberg at gmail.com> wrote: > > I really would like to know how people are using the Story and Example > > runner to write their software. > > It would be great to get some direction on it, because I think I''m missing > > some points. > > > > Taking the outside-in approach in thought: > > > > At first we write a high-level customer-facing story, this story fails. > > Then we start using mocks at object level to use them as a design tool, > > and so we implement the different layers of the system. > > After implementing the inner layer, the story should pass. > > When that happens we could remove the mocks and replace it with calls to the > > real code, > > I do this sometimes - removing the mocks - as long as the objects are > trivial to set up and they don''t have dependencies that I don''t want > to expose. There''s no one way to do this, and I''ll sometimes remove > mocks and reintroduce them over the life of a project. > > > > making the suite less brittle > > What brittle means is a bit subjective here. Just a lengthy > conversation about this in irc last night. The guy with whom I was > chatting prefers to not use mocks because he''d rather see a change > cause a bunch of lower level examples to fail than stories. From what > I can tell, he doesn''t like to use mocks even temporarily, in process. > > His approach has the benefit that you learn about side effects of your > changes faster, and the cost that it means you sometimes have more > "red bar" to wade through while you get things right. > > My approach has the benefit that you can address side effects of your > changes with a green bar helping you know that the smaller bits > (objects and methods) are functioning, and the cost that you sometimes > don''t learn about side effects until you run your stories (or > integration suite). > > Neither solution is perfect. You just have to pick your poison. > > > > (except for calls to external > > services/databases/file systems). > > This is a funny thing about ruby, specifically rails. > > One of the hallmarks of OO is a high level of decoupling - especially > decoupling your code from 3rd party code through adapters. There are a > couple of reasons for this. > > One is that having an adapter lets you write exactly the code that you > want to write throughout most of your system, rather than being > subject to the naming conventions of the 3rd party library that might > clash with those in your system or even with your domain. > > The other is that if you decide to switch to a different library, > you''re pretty well hosed unless you have adapters. If you look at the > competitors to ActiveRecord, like Og and Datamapper, they are all VERY > similar syntactically. Why? Two reasons I think. One is that AR got a > lot of things right from a domain perspective. The other is that calls > to AR internals have leaked out to a lot of controllers and even > views: > > Person.find(:all, :conditions => [''active = ?'', true]) > > In spite of guidelines all over the web that say that this should be > wrapped in a #find_active method in the model, these sorts of things > pop up all over the place anyhow.Finishing up that thought - find_active is an adapter - just at the method level instead of the object level.> > So if the story passes all acceptance tests, why is there a need for > > examples at a lower level? > > So that you can get things working one step at a time, and then change > things as needed one step at a time, with green bars keeping you sane, > stress free, and even happy all the way through. > > HTH, > David >
Pat Maddox
2008-Mar-04 16:43 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
On Tue, Mar 4, 2008 at 6:13 AM, David Chelimsky <dchelimsky at gmail.com> wrote:> What brittle means is a bit subjective here. Just a lengthy > conversation about this in irc last night. The guy with whom I was > chatting prefers to not use mocks because he''d rather see a change > cause a bunch of lower level examples to fail than stories.Do you happen to have a log of that convo? Pat
David Chelimsky
2008-Mar-04 16:46 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
On Tue, Mar 4, 2008 at 10:43 AM, Pat Maddox <pergesu at gmail.com> wrote:> On Tue, Mar 4, 2008 at 6:13 AM, David Chelimsky <dchelimsky at gmail.com> wrote: > > > What brittle means is a bit subjective here. Just a lengthy > > conversation about this in irc last night. The guy with whom I was > > chatting prefers to not use mocks because he''d rather see a change > > cause a bunch of lower level examples to fail than stories. > > Do you happen to have a log of that convo?It was in caboose - are those public?> > Pat > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Pat Maddox
2008-Mar-04 17:11 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
On Tue, Mar 4, 2008 at 8:46 AM, David Chelimsky <dchelimsky at gmail.com> wrote:> > On Tue, Mar 4, 2008 at 10:43 AM, Pat Maddox <pergesu at gmail.com> wrote: > > On Tue, Mar 4, 2008 at 6:13 AM, David Chelimsky <dchelimsky at gmail.com> wrote: > > > > > What brittle means is a bit subjective here. Just a lengthy > > > conversation about this in irc last night. The guy with whom I was > > > chatting prefers to not use mocks because he''d rather see a change > > > cause a bunch of lower level examples to fail than stories. > > > > Do you happen to have a log of that convo? > > It was in caboose - are those public?Nope
Pat Maddox
2008-Mar-04 22:28 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
On Tue, Mar 4, 2008 at 9:11 AM, Pat Maddox <pergesu at gmail.com> wrote:> On Tue, Mar 4, 2008 at 8:46 AM, David Chelimsky <dchelimsky at gmail.com> wrote: > > > > On Tue, Mar 4, 2008 at 10:43 AM, Pat Maddox <pergesu at gmail.com> wrote: > > > On Tue, Mar 4, 2008 at 6:13 AM, David Chelimsky <dchelimsky at gmail.com> wrote: > > > > > > > What brittle means is a bit subjective here. Just a lengthy > > > > conversation about this in irc last night. The guy with whom I was > > > > chatting prefers to not use mocks because he''d rather see a change > > > > cause a bunch of lower level examples to fail than stories. > > > > > > Do you happen to have a log of that convo? > > > > It was in caboose - are those public? > > NopeNevermind, turns out that I work with this nutcase
Dan North
2008-Mar-17 16:08 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
Thanks Chris. This is a really nice description of how I think of BDD. I call it "we should fix that" after Liz Keogh''s blog post: http://sirenian.livejournal.com/42871.html (Check the comments for the myriad ways you can misinterpret this!) Cheers, Dan On 04/03/2008, Chris Parsons <chris at edendevelopment.co.uk> wrote:> > On 4 Mar 2008, at 13:13, Matthijs Langenberg wrote: > > > Taking the outside-in approach in thought: > > > > At first we write a high-level customer-facing story, this story > > fails. > > Then we start using mocks at object level to use them as a design > > tool, > > and so we implement the different layers of the system. > > After implementing the inner layer, the story should pass. > > When that happens we could remove the mocks and replace it with > > calls to the real code, making the suite less brittle (except for > > calls to external services/databases/file systems). > > > Don''t use mocks at the story level. IMHO stories should always be > using the full stack. This includes your database, but you might be > permitted to exclude external services such as credit card billing > systems. However, if you can set up a sandbox to test against (such as > the Paypal sandbox), all to the good. > > We proceed based on two principles: > > A failure in a story means you change specs not code. > A failure in a spec means you change the code. > > This is how we do it (assuming a rails application): > > 1. Write customer story, all steps are pending: > > Scenario: Viewing the front page > When I view the front page > Then I see the text ''welcome to the app'' > > 2. Write the first step in the story: > > When "I view the front page" do > get "/" > end > > This then fails, as I don''t have a front page yet! > > 3. Pay attention to the error given by the story, and fix that *by > writing a spec*. > > In this case it''ll be complaining that the controller doesn''t exist. > At this point I drop down to the specs as a failing story means we > need a spec: > > describe MainController do > end > > 4. Make your specs pass. > > ''rake spec'' then fails, as MainController doesn''t exist. In this case, > I add a controller and a route (by hand, none of that scaffold > business): > > class MainController < ApplicationController > end > > 5. Run the story again if you need to, and use that as a guide to > write more specs. Repeat steps 4 and 5. > > To continue the example - in this case it''ll probably complain about > no index action: > > describe MainController do > it "should handle an index action" do > get :index > end > end > > and then, to fix the spec: > > class MainController < ApplicationController > def index > end > end > > Then it''ll most likely complain about not having an index.html.erb. > Because controller specs don''t render the page, you''ll need an an > index.html.erb_spec.rb to test the view properly. And so on. > > Sound like a lot of work, but given practice you can zip through these > steps very quickly. You also get a free ''focusing tool'' (lose sight of > where you are? just run the story test and write more specs). > > Hope this is helpful. Maybe I should write up an extended example as a > blog post, including mocking etc, as it seems to come up a lot. > > Thanks > Chris > > PS: Excuse the spelling/coding mistakes in the (untested) code :) > Corrections and comments as to the methodology here most welcome. > > -- > Chris Parsons > Managing Director > Eden Development (UK) Ltd > > chris at edendevelopment.co.uk > www.edendevelopment.co.uk > > 0845 0097 094 > po box 425, winchester, so23 0wy, uk > Map: http://pininthemap.com/edendevelopment > > > Tried Pin in the Map? Mark a map location, add text, send to friends. > http://pininthemap.com > > This electronic message and all contents contain information from the > sender which may be privileged, confidential or otherwise protected > from disclosure. The information is intended to be for the > addressee(s) only. If you are not an addressee, any copying, > disclosure, distribution or use of the contents of this message is > prohibited. If you have received this electronic message in error, > please notify the sender by reply e-mail and destroy the original > message and all copies. The sender does not accept liability for any > errors or omissions. > > _______________________________________________ > 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/20080317/df4de8d0/attachment-0001.html
Chuck Remes
2008-Mar-23 02:00 UTC
[rspec-users] What is your workflow? Or how to use the story runner the right way.
On Mar 4, 2008, at 7:43 AM, Chris Parsons wrote:> [snip details about story & spec workflow] > > Sound like a lot of work, but given practice you can zip through these > steps very quickly. You also get a free ''focusing tool'' (lose sight of > where you are? just run the story test and write more specs). > > Hope this is helpful. Maybe I should write up an extended example as a > blog post, including mocking etc, as it seems to come up a lot. > > Thanks > ChrisSorry to resurrect an old thread... I''ve just spent the last 10 hours working on understanding user stories and their role in designing code. Here''s what I''ve done: * watched the "RSpec User Stories" peepcode * scoured this newsgroup for tips & suggestions * used Chris'' methodology to BDD a new app So far things are going well though the process is S L O W. I''ve tried to cobble together tips from other threads regarding directory structure for the stories, steps & specs amongst other things, but it just feels really scattered to me. I would love to see Chris put together a more detailed example of his workflow. It''s likely I am making some boneheaded mistakes that I just can''t pick out yet. When I''m further with my example project, I''ll try to post it up somewhere (or turn it into doc for the rspec site) so others can learn from my mistakes. cr