# \[ANN\] Scenarios, an Alternative to Fixtures

**URL:** <https://www.ruby-forum.com/t/ann-scenarios-an-alternative-to-fixtures/117659>\
**Category:** Rails\
**Created:** [October 19, 2007, 12:27am UTC](https://www.ruby-forum.com/t/ann-scenarios-an-alternative-to-fixtures/117659 "2007-10-19T00:27:00Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![aiwilliams](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/e79b87/32.png) [@aiwilliams](https://www.ruby-forum.com/u/aiwilliams)\
**Post date:** [October 19, 2007, 12:27am UTC](https://www.ruby-forum.com/t/ann-scenarios-an-alternative-to-fixtures/117659/1 "2007-10-19T00:27:00Z")

</div>

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/](http://code.google.com/p/fixture-scenarios/)
2. [http://errtheblog.com/post/7708](http://errtheblog.com/post/7708)
3. [http://rubyforge.org/pipermail/rspec-users/2007-October/003883.html](http://rubyforge.org/pipermail/rspec-users/2007-October/003883.html)
4. [http://faithfulcode.rubyforge.org/svn/plugins/trunk/scenarios/README](http://faithfulcode.rubyforge.org/svn/plugins/trunk/scenarios/README)
