Slide 1

Slide 1 text

TESTING RUBY USING RSPEC WITH FACTORY GIRL AND AUTOTEST Thursday, July 5, 12

Slide 2

Slide 2 text

Why Test? Ensure your code is correct Refactor with confidence Encourages lots of good practices Reference for how code works Thursday, July 5, 12

Slide 3

Slide 3 text

RUBY — TESTING Thursday, July 5, 12

Slide 4

Slide 4 text

THE EMILY WAY Thursday, July 5, 12

Slide 5

Slide 5 text

The Basics Write your test first Test behavior, not implementation “You ain’t gonna need it” Thursday, July 5, 12

Slide 6

Slide 6 text

Test First Test-Driven Development Figure out requirements before you start writing code Interface before implementation Thursday, July 5, 12

Slide 7

Slide 7 text

RED GREEN REFACTOR START Thursday, July 5, 12

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

YAGNI Write only as much code as you need Thursday, July 5, 12

Slide 10

Slide 10 text

YAGNI Write only as much code as you need THIS IS SURPRISINGLY HARD Thursday, July 5, 12

Slide 11

Slide 11 text

RSPEC Thursday, July 5, 12

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Predicate Matchers it.should  be_a_kind_of(klass) it.should  be_true it.should  be_empty it.should  be_present it.should  be_* Thursday, July 5, 12

Slide 18

Slide 18 text

Expect Matchers expect  {  ...  }.to  raise_error expect  {  ...  }.to  throw_symbol expect  {  ...  }.to  yield_control expect  {  ...  }.to  change{  it  } Thursday, July 5, 12

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

FACTORY GIRL Thursday, July 5, 12

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

AUTOTEST Thursday, July 5, 12

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

AND FINALLY... Thursday, July 5, 12

Slide 29

Slide 29 text

DO Write your tests first Use contexts Use shared example groups Test your edge cases Thursday, July 5, 12

Slide 30

Slide 30 text

DON’T Test the framework Test the implementation Get too clever Thursday, July 5, 12