Hi all, In GOOS[1] they use an assertion called assertEventually which samples the system for a success state until a certain timeout has elapsed. This allows you to synchronise the tests with asynchronous code. Do we have an equivalent of that in the Ruby / RSpec world already? I know capybara has wait_until { } but that''s fairly rudimentary - the failure message isn''t very helpful. Is there anything else already out there? [1] http://www.growing-object-oriented-software.com/ cheers, Matt -- Freelance programmer & coach Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak Helles?y) Founder, http://relishapp.com +44(0)7974430184 | http://twitter.com/mattwynne -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110913/cd84b813/attachment.html>
On Tue, Sep 13, 2011 at 6:56 AM, Matt Wynne <matt at mattwynne.net> wrote:> Hi all, > > In GOOS[1] they use an assertion called assertEventually which samples the > system for a success state until a certain timeout has elapsed. This allows > you to synchronise the tests with asynchronous code. > > Do we have an equivalent of that in the Ruby / RSpec world already? I know > capybara has wait_until { } but that''s fairly rudimentary - the failure > message isn''t very helpful. Is there anything else already out there? > > [1] http://www.growing-object-oriented-software.com/ > > cheers, > Matt > > -- > Freelance programmer & coach > Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak > Helles?y) > Founder, http://relishapp.com > +44(0)7974430184 | http://twitter.com/mattwynne > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >the_object.should eventually_call(:foo).within(2).seconds Sounds like Matt is going to make us this matcher! :) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110913/9e685993/attachment-0001.html>
Sure. "wait_for" is a method Brian Takita and I originally wrote for use in Selenium tests, then IIRC it made it into the Selenium gem and now lots of libraries use it (or their own version -- I make no patent claim on polling :-)). The wait_for I remember allowed you to customize the failure message. Let me go see if it''s on GitHub or anything... Ah, here''s one: https://github.com/pivotal/selenium/blob/master/lib/selenium/wait_for.rb (Maybe I should put it in Wrong.) - A On Tue, Sep 13, 2011 at 3:56 AM, Matt Wynne <matt at mattwynne.net> wrote:> Hi all, > In GOOS[1] they use an assertion called assertEventually which samples the > system for a success state until a certain timeout has elapsed. This allows > you to synchronise the tests with asynchronous code. > Do we have an equivalent of that in the Ruby / RSpec world already? I know > capybara has wait_until { } but that''s fairly rudimentary - the failure > message isn''t very helpful. Is there anything else already out there? > [1]?http://www.growing-object-oriented-software.com/ > cheers, > Matt > -- > Freelance programmer &?coach > Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak > Helles?y) > Founder,?http://relishapp.com > +44(0)7974430184 | http://twitter.com/mattwynne > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-- Alex Chaffee - alex at stinky.com http://alexch.github.com http://twitter.com/alexch
> the_object.should eventually_call(:foo).within(2).secondsTDDing multithreaded apps. Good times. Best, Sidu. http://blog.sidu.in On 13 September 2011 20:08, Justin Ko <jko170 at gmail.com> wrote:> > > On Tue, Sep 13, 2011 at 6:56 AM, Matt Wynne <matt at mattwynne.net> wrote: >> >> Hi all, >> In GOOS[1] they use an assertion called assertEventually which samples the >> system for a success state until a certain timeout has elapsed. This allows >> you to synchronise the tests with asynchronous code. >> Do we have an equivalent of that in the Ruby / RSpec world already? I know >> capybara has wait_until { } but that''s fairly rudimentary - the failure >> message isn''t very helpful. Is there anything else already out there? >> [1]?http://www.growing-object-oriented-software.com/ >> cheers, >> Matt >> -- >> Freelance programmer &?coach >> Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak >> Helles?y) >> Founder,?http://relishapp.com >> +44(0)7974430184 | http://twitter.com/mattwynne >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > > the_object.should eventually_call(:foo).within(2).seconds > Sounds like Matt is going to make us this matcher! :) > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Thanks for all the ideas. I just rolled my own which expects a block with an assertion in it: https://gist.github.com/1228927 Could we put this into RSpec somewhere? I''d rather not dump the source into The Cucumber Book - it''s too low level. I could put it into it''s own little gem but that seems like creating clutter in the gemsphere. WDYT? On 13 Sep 2011, at 17:41, Alex Chaffee wrote:> Sure. "wait_for" is a method Brian Takita and I originally wrote for > use in Selenium tests, then IIRC it made it into the Selenium gem and > now lots of libraries use it (or their own version -- I make no patent > claim on polling :-)). The wait_for I remember allowed you to > customize the failure message. Let me go see if it''s on GitHub or > anything... > > Ah, here''s one: > https://github.com/pivotal/selenium/blob/master/lib/selenium/wait_for.rb > > (Maybe I should put it in Wrong.) > > - A > > On Tue, Sep 13, 2011 at 3:56 AM, Matt Wynne <matt at mattwynne.net> wrote: >> Hi all, >> In GOOS[1] they use an assertion called assertEventually which samples the >> system for a success state until a certain timeout has elapsed. This allows >> you to synchronise the tests with asynchronous code. >> Do we have an equivalent of that in the Ruby / RSpec world already? I know >> capybara has wait_until { } but that''s fairly rudimentary - the failure >> message isn''t very helpful. Is there anything else already out there? >> [1] http://www.growing-object-oriented-software.com/ >> cheers, >> Matt >> -- >> Freelance programmer & coach >> Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak >> Helles?y) >> Founder, http://relishapp.com >> +44(0)7974430184 | http://twitter.com/mattwynne >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > > > > -- > Alex Chaffee - alex at stinky.com > http://alexch.github.com > http://twitter.com/alexch > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-userscheers, Matt -- Freelance programmer & coach Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak Helles?y) Founder, http://relishapp.com +44(0)7974430184 | http://twitter.com/mattwynne -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110920/b7e7e5fc/attachment-0001.html>
On Tue, Sep 20, 2011 at 4:55 AM, Matt Wynne <matt at mattwynne.net> wrote:> Thanks for all the ideas. I just rolled my own which expects a block with an > assertion in it:I love the language! eventually { white.should be_black }> Could we put this into RSpec somewhere?It''s not actually RSpec-specific. I''ll put it (or probably a hybrid between your new code and my old code) into Wrong and you can use it via the wrong rspec adapter. def two rand(3) end require "rspec" require "wrong/adapters/rspec" describe "two" do it "should eventually be half of four" do eventually { (two + two).should == 4 } end end should work soonish... -- Alex Chaffee - alex at stinky.com http://alexchaffee.com http://twitter.com/alexch
On 20 Sep 2011, at 23:38, Alex Chaffee wrote:> On Tue, Sep 20, 2011 at 4:55 AM, Matt Wynne <matt at mattwynne.net> wrote: >> Thanks for all the ideas. I just rolled my own which expects a block with an >> assertion in it: > > I love the language! > > eventually { white.should be_black } > >> Could we put this into RSpec somewhere? > > It''s not actually RSpec-specific. I''ll put it (or probably a hybrid > between your new code and my old code) into Wrong and you can use it > via the wrong rspec adapter.Thanks! I know it''s not RSpec specific. I suppose my motivation is I want to keep the number of tools / gems we have to mention in the book to a minimum. Since we''re already using RSpec in the book already it made sense to me if it became part of the RSpec assertion toolkit. I''d have thought it would be useful to other RSpec users too. I''ve never used Wrong, only read about it--and I like the idea very much, I must say. Is there any danger of adverse effects (other than an extra line the Gemfile) if we have to use the Wrong RSpec adapter in the book alongside the existing vanilla RSpec assertions?> > def two > rand(3) > end > > require "rspec" > require "wrong/adapters/rspec" > describe "two" do > it "should eventually be half of four" do > eventually { (two + two).should == 4 } > end > end > > should work soonish... > > -- > Alex Chaffee - alex at stinky.com > http://alexchaffee.com > http://twitter.com/alexchcheers, Matt -- Freelance programmer & coach Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak Helles?y) Founder, http://relishapp.com +44(0)7974430184 | http://twitter.com/mattwynne
On Wed, Sep 21, 2011 at 3:42 AM, Matt Wynne <matt at mattwynne.net> wrote:> I''ve never used Wrong, only read about it--and I like the idea very much, I must say. Is there any danger of adverse effects (other than an extra line the Gemfile) if we have to use the Wrong RSpec adapter in the book alongside the existing vanilla RSpec assertions? >There shouldn''t be, but I''d love for more people to verify that. The adapter source is at https://github.com/sconover/wrong/blob/master/lib/wrong/adapters/rspec.rb (It doesn''t actually do much, just includes Wrong inside RSpec''s ExampleGroup. The bulk of that code is in case anyone uses the Wrong feature "alias_assert" which allows users to define their own DSLy name for assert. I like "expect" but RSpec already has its own "expect"; David kindly provided a way to cleanly remove RSpec''s "expect" before defining my own, but I couldn''t quite get it to work so I''m still using the brute force way which just chops it out using Ruby''s "Module#remove_method" method. In any case, none of that is relevant unless users go out of their way and call "Wrong.config.alias_assert :expect, :override=>true" which most won''t do.) There''s a semantic issue in your eventually method that I''d like to discuss. My wait_for[1] and friends take a *predicate* (in the form of a block) and wait for it to return true(ish). Your eventually[2] ignores the return condition, and merely waits for it to not raise an error. I think using a predicate is more useful, and strictly no less powerful since the waiter code will *also* wait for it to not raise an error, so you could do *either* this eventually { rand(10) == 0 } or this eventually { rand(10).should == 0 } and if, after 2 sec or whatever, it keeps either being false or raising an ExpectationNotMetError, then the waiter will itself raise an ExpectationNotMetError. IOW, should the following pass or should it fail? eventually { false == true } - A P.S. (Lurkers please feel free to chime in too. :-) [1] https://github.com/pivotal/selenium/blob/master/lib/selenium/wait_for.rb [2] https://gist.github.com/1228927 -- Alex Chaffee - alex at stinky.com http://alexchaffee.com http://twitter.com/alexch
On 21 Sep 2011, at 17:46, Alex Chaffee wrote:> There''s a semantic issue in your eventually method that I''d like to > discuss. My wait_for[1] and friends take a *predicate* (in the form of > a block) and wait for it to return true(ish). Your eventually[2] > ignores the return condition, and merely waits for it to not raise an > error. I think using a predicate is more useful, and strictly no less > powerful since the waiter code will *also* wait for it to not raise an > error, so you could do *either* this > > eventually { rand(10) == 0 } > > or this > > eventually { rand(10).should == 0 } > > and if, after 2 sec or whatever, it keeps either being false or > raising an ExpectationNotMetError, then the waiter will itself raise > an ExpectationNotMetError. > > IOW, should the following pass or should it fail? > > eventually { false == true }To be honest, I just ignored the true / false version in my implementation because I want a helpful error message when the test fails, rather than a crude TimeoutError or whatever. I''m ambivalent about this: I would worry that allowing falsiness to cause an assertion to be raised is not idiomatic RSpec, but perhaps it is idiomatic Wrong, since you can do all that magic to infer an error message anyway, right? I think as long as I can use my own assertions too I don''t have any objections to it doing both.> P.S. (Lurkers please feel free to chime in too. :-) > > [1] https://github.com/pivotal/selenium/blob/master/lib/selenium/wait_for.rb > [2] https://gist.github.com/1228927cheers, Matt -- Freelance programmer & coach Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak Helles?y) Founder, http://relishapp.com +44(0)7974430184 | http://twitter.com/mattwynne
On Wed, Sep 21, 2011 at 1:01 PM, Matt Wynne <matt at mattwynne.net> wrote:> I want a helpful error message when the test fails, rather than a crude TimeoutError or whatever.I hear you.> I''m ambivalent about this: I would worry that allowing falsiness to cause an assertion to be raised is not idiomatic RSpec, but perhaps it is idiomatic Wrong, since you can do all that magic to infer an error message anyway, right?I hope so... I mean, uh, yes! Definitely! :-) -- Alex Chaffee - alex at stinky.com http://alexchaffee.com http://twitter.com/alexch
After a week of stealing minutes, I eventually wrote eventually! Please check this out and give me feedback. I can ship it in a new Wrong gem as soon as you all tell me it''s ready. docs: https://github.com/alexch/wrong/commit/cae852f09a3d4dcb3f014b486a10d5eb7a10e7f5 test (spec): https://github.com/alexch/wrong/blob/master/test/eventually_test.rb code: https://github.com/alexch/wrong/blob/master/lib/wrong/eventually.rb The only major feature I haven''t done is editing the error message from inside the block, since Wrong seems to do a good job of this on its own. If the block contains a "should" or a Wrong "assert" then it ends up looking like it just got called and failed the final time. It''d be nice if I could sneak into an exception and append "(after 5 sec)" to e.message but I don''t know if I want to go there... -- Alex Chaffee - alex at stinky.com http://alexchaffee.com http://twitter.com/alexch
On 28 Sep 2011, at 01:09, Alex Chaffee wrote:> After a week of stealing minutes, I eventually wrote eventually! > Please check this out and give me feedback. I can ship it in a new > Wrong gem as soon as you all tell me it''s ready. > > docs: > https://github.com/alexch/wrong/commit/cae852f09a3d4dcb3f014b486a10d5eb7a10e7f5 > > test (spec): > https://github.com/alexch/wrong/blob/master/test/eventually_test.rb > > code: > https://github.com/alexch/wrong/blob/master/lib/wrong/eventually.rb > > The only major feature I haven''t done is editing the error message > from inside the block, since Wrong seems to do a good job of this on > its own. If the block contains a "should" or a Wrong "assert" then it > ends up looking like it just got called and failed the final time. > It''d be nice if I could sneak into an exception and append "(after 5 > sec)" to e.message but I don''t know if I want to go there...I haven''t used it, but this looks good to me.> > -- > Alex Chaffee - alex at stinky.com > http://alexchaffee.com > http://twitter.com/alexch > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-userscheers, Matt -- Freelance programmer & coach Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak Helles?y) Founder, http://relishapp.com +44(0)7974430184 | http://twitter.com/mattwynne
FYI, I''ve just released Wrong 0.6.0 with eventually "as is" -- i.e. no extra exception message fiddling. I also added a message param to Wrong''s "d" method, e.g. d("math is hard") { 2 + 2 } prints math is hard: (2 + 2) is 4 to the console. Useful for debugging (which is what "d" stands for) when you don''t want the test flow to stop with an assert or should. - A -- Alex Chaffee - alex at stinky.com http://alexchaffee.com http://twitter.com/alexch On Sun, Oct 2, 2011 at 2:02 PM, Matt Wynne <matt at mattwynne.net> wrote:> > On 28 Sep 2011, at 01:09, Alex Chaffee wrote: > >> After a week of stealing minutes, I eventually wrote eventually! >> Please check this out and give me feedback. I can ship it in a new >> Wrong gem as soon as you all tell me it''s ready. >> >> docs: >> https://github.com/alexch/wrong/commit/cae852f09a3d4dcb3f014b486a10d5eb7a10e7f5 >> >> test (spec): >> https://github.com/alexch/wrong/blob/master/test/eventually_test.rb >> >> code: >> https://github.com/alexch/wrong/blob/master/lib/wrong/eventually.rb >> >> The only major feature I haven''t done is editing the error message >> from inside the block, since Wrong seems to do a good job of this on >> its own. If the block contains a "should" or a Wrong "assert" then it >> ends up looking like it just got called and failed the final time. >> It''d be nice if I could sneak into an exception and append "(after 5 >> sec)" to e.message but I don''t know if I want to go there... > > I haven''t used it, but this looks good to me. > >> >> -- >> Alex Chaffee - alex at stinky.com >> http://alexchaffee.com >> http://twitter.com/alexch >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > > cheers, > Matt > > -- > Freelance programmer & coach > Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak Helles?y) > Founder, http://relishapp.com > +44(0)7974430184?| http://twitter.com/mattwynne > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >