The new "pending" example feature reminds me of a feature I''ve been bouncing around in my head, to aid in refactoring. Often, when I''m changing existing behaviour, I know that certain aspects of the old behaviour should change. Imagine changing the "it" method to perhaps "not" or "old" or "removed"... The behaviour would be to raise a spec error if the example DOES NOT fail. So if it "should do something that''s been deprecated" do my_object.should_receive(:deprecated_message) action end passes, than old "should do something that''s been deprecated" do my_object.should_receive(:deprecated_message) action end ought to fail. It seems like this might be a good first line of defense when starting a big refactor. I''m not sure about the wording - maybe there''s a better way of expressing it - perhaps as a second argument to the spec (but that would be a little less fun to pepper throughout a document). it "should do something that''s been deprecated", :inverse => true do my_object.should_receive(:deprecated_message) action end Thoughts? Does this exist already and I haven''t noticed it? -- Chris Anderson http://jchris.mfdz.com
On 6/23/07, Chris Anderson <jchris at mfdz.com> wrote:> The new "pending" example feature reminds me of a feature I''ve been > bouncing around in my head, to aid in refactoring. Often, when I''m > changing existing behaviour, I know that certain aspects of the old > behaviour should change. Imagine changing the "it" method to perhaps > "not" or "old" or "removed"... The behaviour would be to raise a spec > error if the example DOES NOT fail. So if > > it "should do something that''s been deprecated" do > my_object.should_receive(:deprecated_message) > action > end > > passes, than > > old "should do something that''s been deprecated" do > my_object.should_receive(:deprecated_message) > action > end > > ought to fail. > > It seems like this might be a good first line of defense when starting > a big refactor. > > I''m not sure about the wording - maybe there''s a better way of > expressing it - perhaps as a second argument to the spec (but that > would be a little less fun to pepper throughout a document). > > it "should do something that''s been deprecated", :inverse => true do > my_object.should_receive(:deprecated_message) > action > end > > Thoughts? Does this exist already and I haven''t noticed it?It doesn''t exist in rspec, but something like it does in rspec_ext: http://rashkovskii.com/articles/2007/1/25/rspec-specify_negatively http://rubyforge.org/projects/rspec-ext/ I haven''t used that, so I don''t know if it works with the latest version or not, but you can give it a shot. As for including this in rspec, I''m not really understanding it''s value. How would saying something should fail, and failing it if it doesn''t, help you (unless you''re writing another behaviour definition framework ;) )?> > -- > Chris Anderson > http://jchris.mfdz.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Thanks for the pointer about rspec-ext, I''ll check it out. On 6/23/07, David Chelimsky <dchelimsky at gmail.com> wrote:> As for including this in rspec, I''m not really understanding it''s > value. How would saying something should fail, and failing it if it > doesn''t, help you (unless you''re writing another behaviour definition > framework ;) )?Not having done it yet, I''m not sure how it would pan out in practice, but the notion is that you''re refactoring to change existing behavior. You''ve got a describe-block, and among the examples are a few that no longer apply. With the objective of maintaining behaviour-driven development, I don''t want to change any code without a failing spec. One helpful way to do that would be with inverse examples. It seems like a 5% case - even most behaviour-changing refactorings force the old behaviour to change, but there have been times I''ve run into old examples, that are passing, and supported by code. But that code is not used anywhere in the application - so the behaviour should have been removed long ago. With inverse examples, you can start a refactor by removing the behaviour you know should not be present. If you just delete the examples, there''s no reason to ever delete the vestigial code. I''ll check out the negative specification - the post you link to has another interesting idea - write negative specs as a form of pending - but I think forcing changes via the inverting of existing examples is more up my alley. -- Chris Anderson http://jchris.mfdz.com
On 6/23/07, Chris Anderson <jchris at mfdz.com> wrote:> Thanks for the pointer about rspec-ext, I''ll check it out. > > On 6/23/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > As for including this in rspec, I''m not really understanding it''s > > value. How would saying something should fail, and failing it if it > > doesn''t, help you (unless you''re writing another behaviour definition > > framework ;) )? > > Not having done it yet, I''m not sure how it would pan out in practice, > but the notion is that you''re refactoring to change existing behavior. > You''ve got a describe-block, and among the examples are a few that no > longer apply. > > With the objective of maintaining behaviour-driven development, I > don''t want to change any code without a failing spec. One helpful way > to do that would be with inverse examples. > > It seems like a 5% case - even most behaviour-changing refactoringsRefactoring == changing the design while preserving existing behaviour, so there is not really any such thing as a behaviour-changing refactoring. What is it that you mean by this? Can you give an example?> force the old behaviour to change, but there have been times I''ve run > into old examples, that are passing, and supported by code. But that > code is not used anywhere in the application - so the behaviour should > have been removed long ago. With inverse examples, you can start a > refactor by removing the behaviour you know should not be present. If > you just delete the examples, there''s no reason to ever delete the > vestigial code. > > I''ll check out the negative specification - the post you link to has > another interesting idea - write negative specs as a form of pending - > but I think forcing changes via the inverting of existing examples is > more up my alley.I''m still not getting this. Call me dense. Would you mind describing a small step-by-step example of how this process would work? Thanks for your patience. David> > -- > Chris Anderson > http://jchris.mfdz.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
I wrote an updated monkey-patch that creates negative examples, using Yurii''s code as inspiration. It seems to work, but I won''t need it for a while. When I try it out, if it is valuable in my workflow, I''ll clean it up as a proper patch or extension. For the time being, you can throw it in your spec_helper.rb and get a rough idea of what it would be like. http://pastie.caboo.se/72927 I decided to name the inverse-it "x" because it''s easy to type and gets the point across. Feel free to rename to your taste in your own projects. On 6/23/07, Chris Anderson <jchris at mfdz.com> wrote:> Thanks for the pointer about rspec-ext, I''ll check it out. > > On 6/23/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > As for including this in rspec, I''m not really understanding it''s > > value. How would saying something should fail, and failing it if it > > doesn''t, help you (unless you''re writing another behaviour definition > > framework ;) )? > > Not having done it yet, I''m not sure how it would pan out in practice, > but the notion is that you''re refactoring to change existing behavior. > You''ve got a describe-block, and among the examples are a few that no > longer apply. > > With the objective of maintaining behaviour-driven development, I > don''t want to change any code without a failing spec. One helpful way > to do that would be with inverse examples. > > It seems like a 5% case - even most behaviour-changing refactorings > force the old behaviour to change, but there have been times I''ve run > into old examples, that are passing, and supported by code. But that > code is not used anywhere in the application - so the behaviour should > have been removed long ago. With inverse examples, you can start a > refactor by removing the behaviour you know should not be present. If > you just delete the examples, there''s no reason to ever delete the > vestigial code. > > I''ll check out the negative specification - the post you link to has > another interesting idea - write negative specs as a form of pending - > but I think forcing changes via the inverting of existing examples is > more up my alley. > > -- > Chris Anderson > http://jchris.mfdz.com >-- Chris Anderson http://jchris.mfdz.com