Peter Marklund's Home |
Rails + RSpec: First Impressions
I started using RSpec on a client project yesterday and I've been pleasantly surprised by how easy it is to get started with and how nicely it plays with Rails. I now have a handful of specs under the spec directory and they get run by rake automatically right after my tests. I can also use rake spec:doc to generate the documentation of my specs:
$ rake spec:doc Admin::StatisticsController - Index page is not viewable by role user or role admin without service id - Index page, role user: shows links - Index page, role super: shows links - Hours page, role user: does not show customer and service selects - Hours page, role super: selects service when service provided - Hours page, role super: selects service when service and customer provided - Hours page, role super: selects customer when customer provided the Call model - Is not deleted by attempt to delete customer - Is not deleted by attempt to delete service the Service model - Is not deleted by attempt to delete customer
I decided to not prefix all my specifications with the "should" keyword, it seemed superfluous. Here are some samples from my controller spec:
Admin::StatisticsController do
fixtures :customers, :services, :users, :services_users, :audio_files, :prompts, :calls
integrate_views
specify "Index page is not viewable by role user or role admin without service id" do
login(:user)
get :index
response.should be_error
login(:admin)
get :index
response.should be_error
end
specify "Index page, role user: shows links" do
login(:user)
get :index, :id => 2
response.should be_success
response.should have_tag("a[href=/admin/statistics/hours/2]")
response.should have_tag("a[href=/admin/statistics/calls/2]")
end
...
######################################################
#
# Helper methods
#
######################################################
login_user(user_for_role(role))
end
case role
when :super
users(:aaron)
when :admin
users(:admin)
when :user
users(:customer)
else
raise "Unknown role "
end
end
@controller.send(:session=, ActionController::TestSession.new)
@controller.send(:current_user=, user)
end
end
describe
I think it's very refreshing to switch to RSpec from unit tests. The syntax is more readable and makes it feel natural to write specs/tests before the code. In this particular case though I wrote the spec first, but when I started implementing the UI I changed my mind about which page the form should go on, experimented with the UI a bit, and ended up writing the spec after the fact. I don't consider this a deadly sin. One probably shouldn't be too religious about writings specs before the code in cases where it slows you down too much or hinders your creativity.
I highly recommend you try out RSpec with Rails if you haven't already.