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!