[ANN] Scenarios, an Alternative to Fixtures

Being fully aware of the work of Mr. Preston-Werner[1] and
err.the.blog[2], we present to you Scenarios, a somewhat different
approach[3] to alleviating the pain of managing table data for a Rails
application under test.

A simple scenario looks like this:

in spec/scenarios/users_scenario.rb

class UsersScenario < Scenario::Base
def load
create_record :user, :john, :name => ‘John’, :password =>
‘doodaht’
create_record :user, :cindy, :name => ‘Cindy’, :password =>
‘whoot!’
end
end

To use the UsersScenario in an RSpec description, you should declare
it using
the scenario method:

in spec/models/user_spec.rb

describe User do
scenario :users

it "should allow me to do something with John" do
  user = users(:john)
  user.password.should == "doodaht"
end

end

In real life your scenarios will probably grow quite complicated. The
scenarios plugin allows you to deal with this complexity through
composition.

Here’s a simple example:

in spec/scenarios/posts_scenario.rb

class PostsScenario < Scenario::Base
def load
create_record :post, :first, :title => “First Post”
create_record :post, :second, :title => “Second Post”
end
end

in spec/scnearios/comments_scenario.rb

class CommentsScenario < Scenario::Base
uses :posts

def load
  create_record :comment, :first, :body => "Nice post!", :post_id

=> post_id(:first)
create_record :comment, :second, :body => “I like it.”, :post_id
=> post_id(:first)
create_record :comment, :third, :body => “I thoroughly
disagree.”, :post_id => post_id(:second)
end
end

When you use a scenario, you get any help the scenario provides made
available to your RSpec examples.

in spec/scenarios/users_scenario.rb

class UsersScenario < Scenario::Base
def load
create_user :name => “John”
end

helpers do
  def create_user(attributes={})
    create_record :user, attributes[:name].downcase.intern,

attributes
end
def login_as(user)
@request.session[:user_id] = user.id
end
end
end

in spec/controllers/projects_controller_spec.rb

describe “Projects screen” do
scenario :users

it "should show active projects" do
  login_as(users(:john))
  get :projects
  @response.should have_tag('#active_projects')
end

end

You can load your scenarios into your development database, too!

rake db:scenario:load SCENARIO=comments

Scenarios works by doing direct inserts instead of using ActiveRecord
instances - there is no validation - similar to the way the current
fixtures implementation works.

You may find greater detail at the RubyForge project site[4]. Any
feedback from those seeing value and giving it a spin is greatly
appreciated.

Adam W.

  1. http://code.google.com/p/fixture-scenarios/
  2. http://errtheblog.com/post/7708
  3. http://rubyforge.org/pipermail/rspec-users/2007-October/003883.html
  4. http://faithfulcode.rubyforge.org/svn/plugins/trunk/scenarios/README