Before and After

before(:each) and after(:each)

RSpec provides methods that let you set up and tear down state before(:each)
and after(:each) example.

describe Account do
  before(:each) do
    @account = Account.new
  end

  it "should have a balance of $0" do
    @account.balance.should == Money.new(0)
  end
  
  after(:each) do
    # this is here as an example, but is not really
    # necessary. Since each example is run in its
    # own object, instance variables go out of scope
    # between each example.
    @account = nil
  end
end

Note that after(:each) is rarely needed, and should only really be used when concerned
that some state might be leaking into your other examples.

before(:all) and after(:all)

For expensive operations, like opening browsers using Spec::Ui, RSpec also allows
you to set up and tear down state before(:all) and after(:all) examples in any
given behaviour.

describe "Search page" do
  before(:all) do
    @browser = Watir::Browser.new
  end

  it "should find all contacts" do
    ...
  end
  
  after(:all) do
    @browser.kill! rescue nil
  end
end

Global after and before blocks

Sometimes you have some generic code you want to run before or after every single one of your
examples. Such global before and after blocks can be defined in the RSpec configuration, which
typically lives in a spec_helper.rb file that is required from other spec files. Example:

Spec::Runner.configure do |config|
  config.before(:all) {}
  config.before(:each) {}
  config.after(:all) {}
  config.after(:each) {}
end

Global before blocks get run before local ones. Global after blocks get run after local ones.

You can also specify that a before or after block should only be weaved into certain behaviours,
in a similar way to how global includes are declared:

Spec::Runner.configure do |config|
  config.before(:each, :type => :controller) do
    login_aslak
  end
end

When before and after raise errors

If a before block raises an error, none of the following before blocks (if any) or the example itself will get run.
If an after block raises an error, the remaining ones will still be run.

WARNING ABOUT before(:all) and after(:all)

It is very tempting to use before(:all) and after(:all) for situations in which it
is not appropriate. before(:all) shares some (not all) state across multiple examples. This means
that the examples become bound together, which is an absolute no-no in testing. You
should really only ever use before(:all) to set up things that are global collaborators
but not the things that you are describing in the examples.

The most common cases of abuse are database access and/or fixture setup. Every example
that accesses the database should start with a clean slate, otherwise the examples become
brittle and start to lose their value with false negatives and, worse, false positives.