[rspec-users] before before and after after

aslak hellesoy aslak.hellesoy at gmail.com
Mon Apr 16 18:39:17 EDT 2007

Dave and I have just had a lengthy chat about this and I think we've
come up with a pretty elegant solution for an API. It's inspired from
the filter chaining mechanism in Rails.

Essentially you can specify several before and after blocks. This is
actually already supported in RSpec.
What we need is a mechanism that allows users to have more fine
grained control of the order in which
these blocks are executed, and we're thinking of supporting this with
4 basic methods:

#prepend_before(where=:each, &proc)
#append_before(where=:each, &proc)
#prepend_after(where=:each, &proc)
#append_after(where=:each, &proc)

Further, #before will be an alias for #append_before and #after will
be an alias for #prepend_after.
This allows users to just write before{..} and after{..} if they don't
care about the order.

This means that globally specified #before blocks (typically in a
spec_helper.rb via Spec::Runner#configure, which usually gets loaded
before everything else)
will be executed before any #before blocks in individual specs. The
opposite will be the case for #after blocks.

However, for those of you who wish to execute a #before block *before*
the global #before block, you can use #prepend_before
in the specs that want to do this.

Finally, the #before(:all) blocks will be executed before
#prepend_before(:each) blocks - the +where+ argument trumps the

None of this is implemented yet, so please chime in soon if you have
any comments about this.


On 4/16/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> Hi all,
> There are currently a number of ways to extend RSpec that are
> documented inconsistently and work in sometimes conflicting and/or
> confusing ways. I'd like to resolve that. The recent addition of
> Spec::Runner.configure is part of that resolution.
> The thing I want to tackle now is the stuff that happens before and
> after each example. Currently (in trunk), things are executed in the
> following order:
> describe Thing do
>   before(:all) do
>     #happens first, but only once within this "describe" block
>   end
>   before(:each) do
>     #happens before each example within this "describe" block
>   end
>   it "should ..." do
>     #this is the example
>   end
>   after(:each) do
>     #happens after each example within this "describe" block
>   end
>   after(:all) do
>     #happens last, but only once within this "describe" block
>   end
> end
> In addition to this, there have been requests to support global
> "before" and "after". Here's where I'd like to end up:
> Spec::DSL::Example.before(:first) do
>   # before "before(:all)" and "before(:each)"
> end
> Spec::DSL::Example.before(:last) do
>   # after "before(:all)" and "before(:each)", but before the example
> end
> Spec::DSL::Example.after(:first) do
>   # before "after(:each)" and "after(:all)", but after the example
> end
> Spec::DSL::Example.after(:last) do
>   # after "after(:each)" and "after(:all)"
> end
> So the over all order for every example (a.k.a. specify) would be:
> before(:first)
> before(:all) #once per "describe"
> before(:each)
> before(:last)
> example
> after(:first)
> after(:each)
> after(:all) #once per "describe"
> after(:last)
> I'm certainly open to other suggestions - this is merely a proposal.
> In most cases you wouldn't use all of these. In fact, you may not use
> any of them if you prefer the Object Mother approach (helper methods
> that create the state you want to start with). But this would give you
> a lot of choice at both global and granular levels.
> WDYT? Too confusing? Too limiting? Just right?
> Thanks,
> David
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

More information about the rspec-users mailing list