Scenario

Scenarios is a super-simple way to move common setup and helper methods into cohesive “scenarios” that can be included easily in your specs. The advantage of a scenario over regular mixin modules is that you can use RSpec hooks (eg. before :each {}) to do the setup instead of having redundant, copy-pasted setup littering your specs.

Scenario also includes a basic DSL for performing setup atomically. That is, instead of doing expensive setup in a before :all block that is always run, you can run only the setup that you need in a given describe with the Scenario DSL.

Examples

# Describe your scenarios:

describe_scenario :user do
  before :all do
    @user = User.create( :name => "Bob", :password => "foo", :admin => false )
  end
  
  def login
    visit( url( :login ) )
    fill_in :name, :with => "Bob"
    fill_in :password, :with => "foo"
    click_button "Login"
    response
  end
end

describe_scenario :admin do
  before :all do
    @user = User.create( :name => "Sally", :password => "bar", :admin => true )
  end
  
  def login
    visit( url( :login ) )
    fill_in :name, :with => "Sally"
    fill_in :password, :with => "bar"
    click_button "Login"
    response
  end
end

# Write your specs:

describe "Logging in" do
  describe "as an user" do
    scenario :user
    
    it "should log them in" do
      login.should be_successful
    end
  end
  
  describe "as an admin" do
    scenario :admin
    
    it "should log them in" do
      login.should be_successful
    end
  end
end

Because scenarios are simply blocks that are run in the context where they are included, you can use as many as you want:

describe "GET /message/new when database is down" do
  scenario :user
  scenario :database_down
  
  it "should show fail whale" do
    visit( "/message/new" )
    response.should contain( "fail whale" )
  end
end

And you can nest them:

describe "GET /message/new" do
  scenario :user
  
  describe "when database is up" do
    it "should not show fail whale" do
      visit( "/message/new" )
      response.should_not contain( "fail whale" )
    end
  end
  
  describe "when database is down" do
    scenario :database_down
    
    it "should show fail whale" do
      visit( "/message/new" )
      response.should contain( "fail whale" )
    end
  end
end

Setup

Setup is executed before :all.

describe_scenario :user do
  setup_for :user do |name, password|
    name ||= "Bob"
    password ||= "foo"
    @user = User.create( :name => name, :password => password )
  end
  
  setup_for :admin do |name, password|
    name ||= "Sally"
    password ||= "bar"
    @user = User.create( :name => name, :password => password, :admin => true )
  end
  
  def login
    visit( url( :login ) )
    fill_in :name, :with => "Bob"
    fill_in :password, :with => "foo"
    click_button "Login"
    response
  end
end

# Pass a hash:

describe "One user" do
  scenario :user, :setup => :user
  
  it "has one user" do
    User.count.should == 1
  end
end

describe "Two users" do
  scenario :user, :setup => [:user, :admin]
  
  it "has two users" do
    User.count.should == 2
  end
end

# Or pass a block:

describe "One user" do
  scenario :user do
    setup_user( "Sam" )
  end
  
  it "has one user" do
    User.count.should == 1
  end
end

# Or both!

describe "Two users" do
  scenario :user, :setup => :user do
    setup_admin( "Steph" )
  end
  
  it "has two users" do
    User.count.should == 2
  end
end

Fixtures

Basic fixture support is also included. (Please note that fixtures are currently hard-coded to spec/scenarios/fixtures. It will be configurable in a future version. Feel free to open a pull request or just monkey patch the root() method.

Scenario::Fixtures['html/sample.html'] # Returns contents of the fixture as a string

Scenario::Fixtures caches the contents of the file so that the file only needs to be read once.

Version History

Contributing to Scenario

Copyright

Copyright © 2011 Tyson Tate. See LICENSE.txt for further details.