RSpec 2 Best practices

957,048 views
1,083,778 views

Published on

A list of some best practices I've been learning during my daily job.

Published in: Technology
1 Comment
87 Likes
Statistics
Notes
No Downloads
Views
Total views
957,048
On SlideShare
0
From Embeds
0
Number of Embeds
869,074
Actions
Shares
0
Downloads
311
Comments
1
Likes
87
Embeds 0
No embeds

No notes for slide

RSpec 2 Best practices

  1. 1. Rspec Best Practices Ruby Social Club Milano 24 February 2011 Andrea Reginato twitter/andreareginato
  2. 2. Ill not teach RSpecYou have good books and web sites The RSpec Book Rails Test Prescriptions twitter/andreareginato
  3. 3. Ill tell you how I use RSpec What Ive learned reading books some articles on the web but most important from my everyday job experience twitter/andreareginato
  4. 4. Just a little introduction RSpec is a library that focus on testing the behavior of your everyday project twitter/andreareginato
  5. 5. Why people do not use it Probably the testing practice is the most diffcult forma mentis a developer have to learn twitter/andreareginato
  6. 6. It will save our life, maybe In the long term, you will not check your web page everytime you make a new feature, but you will check if your test passed twitter/andreareginato
  7. 7. Short descriptions# wrongit "should have 422 status code if an unexpected params will be added" do response.should respond_with 422end# correctcontext "when not valid" it { should respond_with 422 }
  8. 8. (over)use contexts and use with/when as keys# wrongit "should have 200 status code if logged in" do response.should respond_with 200end# correctcontext "when logged out" do it { should respond_with 401 }end
  9. 9. Describe methods# wrongdescribe "the authenticate method for User logged in" ...describe "if the user is an admin" do# correctdescribe ".authenticate" dodescribe "#admin?"
  10. 10. Single expectation test# wrongit "should create a resource" do response.should respond_with_content_type(:json) response.should assign_to(:resource)end# correctit { should respond_with_content_type(:json) }it { should assign_to(:resource) }
  11. 11. Test the edge cases# sample actiondef destroy @resource = Resource.where(:id => params[:id]) if @resource @resource.destroy head 204 else render :template => "shared/404", :status => 404, endendWhat would you test ?
  12. 12. Test the edge case# correctdescribe "#destroy" do context "when resource is found" do it "should render_with 204" it "should assign @resource" context "when resource is not found" do it "should render with 404" it "should not assign @resource" endendIs this enough ?
  13. 13. Use the subject# wrongit { assigns("message").should match /The resource name is Genoveffa/ }it { assigns("message").should match /it was born in Billyville/ }it { assigns("message").creator.should match /Claudiano/ }# correctsubject { assigns("message") }it { should match /The resource name is Genoveffa/ }it { should match /it was born in Billyville/ }its(:creator) { should match /Claudiano/ }
  14. 14. Mock or not to mock# wrong (a really personal point of view)1) Its wrong when you never mock and recreate by codea “medium complex” situation and its time consuming2) Its wrong when you mock everything. You have a lightsystem and the big advantage of independence, but you loosepart of the control on your application.# correct# simulate authenticated usercontroller.stub!(:authenticate).and_return(true)# simulate current usercontroller.stub(:current_user).and_return(current_user)# simulate not found recordResource.stub(:where).with(created_from: id) .and_return(false)
  15. 15. Create data when needed# wrongYou shouldnt use fixtures* loose control on our data* load everything all the time* difficult to find problems# correctdescribe "User" describe ".top" do before { 3.times { Factory(:user) } } it { User.top(2).should have(2).item } endend
  16. 16. Shared examples to DRY# wrongcontext "when own resources" do it "should have it" do resource = Factory("user") do_get format: json assigns(users).should include(resource) endendcontext "when does not own resource" do it "should not have it" do not_owned_resource = Factory("unknown") do_get format: json assigns(users).should_not include(not_owned_resource) endend
  17. 17. Shared examples to DRY# correct (but why?)shared_examples for "a secure resource" do context "when own the resource" do it "should have it" do resource = Factory("user") do_get format: json assigns(users).should include(resource) end end context "when does not own resource" do it "should not have it" do not_owned_resource = Factory("unknown") do_get format: json assigns(users).should_not include(not_owned_resource) end endend
  18. 18. Shared examples to DRY# correct (apply DRY on tests)describe "#show" do it_should_behave_like "a secure resource" it_should_behave_like "a findable resource" it_should_behave_like "a secure resource" context "when not logged in" do it_should_handle "a not authenticated request" endend
  19. 19. More?# wrongDo not use RSpec# correctStart using RSpec 2 into your next project
  20. 20. Thanks# more infoThere is a public google doc that Ive started with some friends,and whenever you want you can write me# contactsandrea.regianto@gmail.comtwitter/andreareginato

×