Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing Ruby

Testing Ruby

A fairly high-level intro to testing Ruby using RSpec, Factory Girl, and Autotest.

Emily Hyland

July 05, 2012
Tweet

More Decks by Emily Hyland

Other Decks in Programming

Transcript

  1. Why Test? Ensure your code is correct Refactor with confidence

    Encourages lots of good practices Reference for how code works Thursday, July 5, 12
  2. The Basics Write your test first Test behavior, not implementation

    “You ain’t gonna need it” Thursday, July 5, 12
  3. Test First Test-Driven Development Figure out requirements before you start

    writing code Interface before implementation Thursday, July 5, 12
  4. Test Behavior Behavior-Driven Development Unit tests are sentences starting with

    “it should” Use mocks for outside collaborators Changing the implementation shouldn’t break the test Thursday, July 5, 12
  5. YAGNI Write only as much code as you need THIS

    IS SURPRISINGLY HARD Thursday, July 5, 12
  6. Why RSpec? Tests are very easy to read Syntax encourages

    good practices Specify behavior instead of verifying state Tests as documentation Tests are more expressive and more maintainable Thursday, July 5, 12
  7. describe  Array  do    context  "when  empty"  do    

       subject  {  Array.new  }        it  {  should  be_empty  }        its(:first){  should  be_nil  }        its(:length){  should  ==  0  }    end end Basic Syntax Thursday, July 5, 12
  8. More Syntax let(:user){  User.new  } before{  set_current_user(user)  } it  "should

     be  reasonable"  do    "foo".should_not  eq("bar") end it  "should  be  magic"  do    pending  "invent  magic" end Thursday, July 5, 12
  9. Shared Examples shared_examples  "collections"  do  | klass|    it  "is

     empty  when  first  created"  do        klass.new.should  be_empty    end end describe  Array  do    include_examples  "collections",  Array end Thursday, July 5, 12
  10. Matchers it.should  eq(expected) it.should  ==  expected it.should  be(expected) it.should  equal(expected)

    it.should  be  >  minimum it.should  be_within(x).of(y) Thursday, July 5, 12
  11. Expect Matchers expect  {  ...  }.to  raise_error expect  {  ...

     }.to  throw_symbol expect  {  ...  }.to  yield_control expect  {  ...  }.to  change{  it  } Thursday, July 5, 12
  12. On Rails Different file layout than with Test::Unit Directories for

    model, controller, helper, and view specs Lots of Rails-specific matchers, etc. Thursday, July 5, 12
  13. Model Classic unit test Test each model individually Ideally, isolate

    from the database Check validations, but indirectly Add a context for each non-trivial method Thursday, July 5, 12
  14. Controller Did you get the right response code? Did the

    expected redirect happen? Were the correct instance variables set? Were the right flash messages displayed? Thursday, July 5, 12
  15. Legacy Write tests for what you have before you change

    it Write a failing test before you fix a bug Don’t try to do it all at once Thursday, July 5, 12
  16. Why Factories? Fixtures quickly get hard to maintain “What did

    I call the fixture for my admin user without an email?” Create the right object when you need it Use templates to keep it DRY Thursday, July 5, 12
  17. Syntax FactoryGirl.define  do    factory  :user  do      

     name  "John  Doe"        factory  :admin  do            admin  true        end    end end FactoryGirl.build(:user) Thursday, July 5, 12
  18. Why Autotest? Never forget to run your tests again Get

    nearly instant notification when you break something Run the right tests at the right time Thursday, July 5, 12
  19. DO Write your tests first Use contexts Use shared example

    groups Test your edge cases Thursday, July 5, 12