On Thu, Jul 9, 2009 at 9:37 AM, Daniel Tenner<daniel.rs...@tenner.org> wrote: >> 2) Is it your goal to call "some_expensive_operation" once and only once? > > Yes, exactly. In the case of the project archival spec, creating a project, > archiving it, and then unzipping it to a temporary location to look at what > was archived is a process that takes about 3 seconds on my machine. Since > archival isn't something people will be doing live on the site, speed is not > an issue from a user point of view. However, there's about 25 specs (in > about a dozen sub-contexts) examining the zip output... multiply that by 3 > seconds each, and that takes more time to run than all the other specs > combined! > I have actually managed to get this done using the method described in my > blog post @ > http://www.swombat.com/getting-rspec-beforeall-and-nested-contexts-w , but I > have to admit it's a bit hackish. > David - ":apply_to_nested => false" seems like a great way to do it, but I > understand why you'd want to get the refactoring out of the way first. With > my temporary hack in place, I can wait.
My message about refactoring was back in January :) If you're interested in supplying a patch I'd be interested in accepting it. > Thanks, > Daniel > On Thu, Jul 9, 2009 at 3:22 PM, Zach Moazeni <zach.li...@gmail.com> wrote: >> >> Rereading your original email, I'm thinking I may not have entirely >> understood your situation. >> >> 1) Looks like you've already defined the "some_expensive_operation" (but >> that's minor) >> >> 2) Is it your goal to call "some_expensive_operation" once and only once? >> >> On Jul 9, 2009, at 10:18 AM, Zach Moazeni wrote: >> >>> Hey Dan, >>> >>> 1 approach you could do is define a method within the outer describe that >>> is called within the inner describe and within each test not contained by an >>> inner describe. >>> >>> describe "Some functionality" do >>> it "should do something" do >>> @variable = some_expensive_operation >>> @variable.should do_something >>> end >>> >>> describe "in a specific context" do >>> before(:all) do >>> @variable = some_expensive_operation >>> end >>> >>> it "should do another thing" do >>> @variable.should do_another_thing >>> end >>> end >>> >>> def some_expensive_operation >>> p "in here" >>> end >>> end >>> >>> (also uploaded to http://gist.github.com/143693) >>> >>> My solution is to unDRY the subcontext's preconditions. I have pretty >>> strong opinions about DRYing up specs at the cost of grokability. >>> >>> On Jul 9, 2009, at 6:40 AM, Daniel Tenner wrote: >>> >>>> Hi all, >>>> >>>> Like everyone (?), I use nested contexts to keep my specs well organised >>>> and tidy. >>>> >>>> However, I have a problem. I have various sets of specs that needs to >>>> perform very time-expensive operations to set up the fixtures that will be >>>> examined in the tests. Two specific examples: testing access control logic >>>> (requires creating a whole tree of items to verify the correct access level >>>> against each item), and project archival (which creates a project, fills it >>>> with test data, archives/zips the project contents, then unzips them for >>>> examination). >>>> >>>> I tried using before(:all) to set up those costly fixtures, however I >>>> hit upon a feature of rspec that made that less than successful: >>>> >>>> When using before(:all) along with nested contexts, rspec actually >>>> re-runs the before(:all) before each sub-context. So if, like me, you have >>>> your specs neatly organised in sub-contexts, the before(:all) is actually >>>> re-run many times. >>>> >>>> Interestingly, when a before(:all) is run in the root context, rspec >>>> does not actually remove the data from the database when re-running the >>>> before(:all). "Great," I then thought, "I can just detect whether the data >>>> is created and decide whether or not to create the objects on that basis". >>>> Not so fast, though: Rspec may not clobber the database, but it does >>>> clobber >>>> instance variables. In the case of the access control test, there's about >>>> 40 >>>> different instance variables, so keeping track of them all manually in some >>>> global variable outside of rspec would be messy to say the least... >>>> >>>> So my question is, is there any workaround for successfully using >>>> before(:all) and nested specs, so that code like the following works and >>>> doesn't run the expensive operation more than once: >>>> >>>> describe "Some functionality" do >>>> before(:all) do >>>> @variable = some_expensive_operation >>>> end >>>> >>>> it "should do something" do >>>> @variable.should do_something >>>> end >>>> >>>> describe "in a specific context" do >>>> it "should do another thing" do >>>> @variable.should do_another_thing >>>> end >>>> end >>>> end >>>> >>>> Worth noting that I'm quite happy to give up the ability to have before >>>> blocks in the sub-contexts in order to ensure that the expensive operation >>>> is only run once... >>>> >>>> Your thoughts most welcome... (including, perhaps, telling me that I'm >>>> Doing It Wrong) >>>> >>>> Daniel Tenner >>>> http://www.woobius.com >>>> http://danieltenner.com >>>> _______________________________________________ >>>> rspec-users mailing list >>>> rspec-users@rubyforge.org >>>> http://rubyforge.org/mailman/listinfo/rspec-users >>> >>> -- >>> Zach Moazeni >>> http://simplechatter.com >>> >>> >>> >> >> -- >> Zach Moazeni >> http://simplechatter.com >> >> >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users@rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users