Hornsby

A Scenario Builder without the fixture pain.

Usage

Scenarios look like:

scenario :apple do
  @apple = Fruit.create! :species => 'apple'
end

scenario :orange do
  @orange = Fruit.create! :species => 'orange'
end

scenario :fruitbowl => [:apple,:orange] do
  @fruitbowl = FruitBowl.create! :fruit => [@apple,@orange]
end

scenario :kitchen => :fruitbowl do
  @kitchen = Kitchen.create! :fruitbowl => @fruitbowl
end

…and you use them in specs like:

describe Fruit, "@apple" do
  before do
    hornsby_scenario :apple
  end

  it "should be an apple" do
    @apple.species.should == 'apple'
  end
end

describe FruitBowl, "with and apple and an orange" do
  before do
    hornsby_scenario :fruitbowl
  end

  it "should have 2 fruits" do
    @fruitbowl.should have(2).fruit
  end
end

All scenarios are run only once, no matter how many times they were called, meaning that you don't need to worry about duplicating data.

There's also a possibility to delete preloaded data with hornsby_clear. When called without arguments it will drop all data. You can also pass it table names, that will be cleared of any data. Beware that any scenarios already executed will still be marked as executed, so you won't be able to execute them again. If you want to execute those scenarios later in test, you can pass :undo option with list of scenarios to mark as not executed or :all if you want to mark that no scenario has been executed.

hornsby_clear :fruits, :trees # Deletes trees and fruits tables
hornsby_clear # Deletes all data except tables that are defined by Hornsby.skip_tables
hornsby_clear :fruits, :undo => :apples # Deletes fruits table and marks :apples scenario as not executed
hornsby_clear :undo => :all # Deletes all tables and marks all scenario as not executed (fresh start)

Hornsby searches for scenario files in this particular order in Rails (Merb) root:

  • hornsby_scenarios.rb

  • hornsby_scenarios/*.rb

  • hornsby_scenario.rb

  • hornsby_scenario/*.rb

  • spec/hornsby_scenarios.rb

  • spec/hornsby_scenarios/*.rb

  • spec/hornsby_scenario.rb

  • spec/hornsby_scenario/*.rb

  • test/hornsby_scenarios.rb

  • test/hornsby_scenarios/*.rb

  • test/hornsby_scenario.rb

  • test/hornsby_scenario/*.rb

You can pass :root option to override framework root and :filename option to pass custom filename pattern

Setup

The easiest way to install this gem for Ruby on Rails is just add this line to config/environment.rb (or config/environments/test.rb):

config.gem 'sinsiliux-hornsby', :lib => 'hornsby', :source => 'http://gems.github.com'

If you’re not using rails, then you can install it through command line

gem sources -a http://gems.github.com
sudo gem install sinsiliux-hornsby

Lastly you could use it as plugin:

ruby script/plugin install git://github.com/sinsiliux/hornsby.git

Hornsby scenarios is activated by calling enable_hornsby. For specifics on how to call that in your testing framework see a little lower. enable_hornsby supports these parameters:

  • root - custom framework root if automatic detection fails for some reason (eg. not rails/merb project)

  • filename - custom files pattern with hornsby scenarios

  • scenarios - list of hornsby scenarios that should be preloaded (available in all tests, never reloaded so they're much faster)

RSpec

Add the following to spec_helper.rb

Spec::Runner.configure do |config|
  ...

  config.enable_hornsby :filename => 'scenarios.rb', :scenarios => :preloaded_scenario
end

Test::Unit

Add the following lines to test_helper.rb

class ActiveSupport::TestCase
  ...

  enable_hornsby
end

Advanced Usage

Its just ruby, right? So go nuts:

1.upto(9) do |i|
  scenario("user_#{i}") do
    user = User.create! :name => "user#{i}"
    instance_variable_set("@user_#{i}",user)
  end
end

Transactions

Hornsby scenarios is transactional, meaning that after every test transaction is dropped and database is reset to starting point. Starting point is empty database + any scenarios that you specify in configure_rspec.

Rake

If you'd like simply to load your scenarios into a database, use the rake task like so:

$ rake hornsby:scenario RAILS_ENV=test SCENARIO=fruitbowl

TODO

  • Add scenario namespaces for better organisation.

  • Add ability to revert one scenario.

  • Add preloading scenarios for whole block of tests.

Credits

Lachie Cox <lachie@smartbomb.com.au>

Andrius Chamentauskas <sinsiliux@gmail.com>

The code is based on Err's code found in this post: errtheblog.com/post/7708

License

MIT, see LICENCE