Update: I’ve made some improvements upon this using WebRat that you can read all about here.
I’m having a great time with RSpec‘s new StoryRunner, and wanted to share a bit of what you can do with it. I learn very well from examples and I know many others do as well so I hope that this provides as a useful resource for getting your ideas flowing on how to use StoryRunner for your own projects.
To start, I set up a simple project using the following
# Create the project rails blog cd blog # Install Restful Authentication script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/ script/generate authenticated user sessions # Create a Post model script/generate scaffold post title:string body:text published:boolean
Now I have the essentials for a simple app to play with. Of course you’ll also want to install RSpec.
Now to try out StoryRunner! I’ll write a story to cover the login system. No need to write Spec’s for it, it’s already well tested. However in writing this story we get a reusable Scenario that will be nice to have later, as well as give us a nice starting point for stories.
require File.join(File.dirname(__FILE__), "helper") Story "User Stuff", %{ As a writer I want to be a member So that I can make posts }, :type => RailsStory do Scenario "I log in as a new user" do Given("that I am not logged in") do delete "/sessions/destroy" controller.should_not be_logged_in @user_count = User.count end When("I create a new user", "Glenn") do |name| @user = User.create(:login => name, :email => "#{name}@glennfu.com", :password => name, :password_confirmation => name) end Then("there should be 1 more user stored") do User.count.should == @user_count + 1 end When("I login as", "Glenn") do |name| post "/sessions/create", :login => name, :password => name end Then("I should be logged in") do controller.should be_logged_in response.should be_redirect end end end
This should be pretty easy to follow. I start by logging out, then creating a user and logging in with it. This is runnable with ruby stories/user_story.rb
Now that this is already written, we can easily add similar stories. Notice that we don’t have to re-define our steps here:
Scenario "I log in with the wrong user/password" do Given "that I am not logged in" When "I create a new user", "Glenn" Then "there should be 1 more user stored" When "I login as", "JoeBob" Then "I should not be logged in" do controller.should_not be_logged_in response.should_not be_redirect end end
Now I’ll write a story for our Posts. Notice the usage of “GivenScenario”, very cool!
Scenario "Create a new post while logged in" do GivenScenario "I log in as a new user" Then "I should be able to make a post" do post "/posts/create", :post => {:title => "the title", :body => "The body!"} @post = Post.find_by_title("the title") flash[:notice].should == "Post was successfully created." @post.should_not be_nil response.should be_redirect end end
What if I want to also test posts failing? I’ll modify the previous step to be a bit more robust (and also more useful).
Then "I $should be able to make a post", "should" do |should| post "/posts/create", :post => {:title => "my title", :body => "The body!"} @post = Post.find_by_title("my title") if should == "should" flash[:notice].should == "Post was successfully created." @post.should_not be_nil else flash[:notice].should be_nil @post.should be_nil end response.should be_redirect end
With this change, I can easily add a new Scenario to test when making posts should fail:
Scenario "Create a new post while not logged in" do Given "that I am not logged in" Then "I $should be able to make a post", "should not" end
I hope you found this useful!