Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Test First Teaching and the path to TDD
Who am I?Sarah Allen@ultrasaurus
Why should you care?•   you want to improve your Ruby skills•   you want to do testing (better)•   you have a friend or co...
by teaching, you learn...•   the best engineers are good teachers•   we live and work in collaborative    environments•   ...
What is        Test-First Teaching?•   teacher provides microtests•   student makes them pass    •   one test at a time•  ...
Pairing Is Teaching
Pairing in the classroom   •   students learn together and teach each other   •   each pair can proceed through exercises ...
How do we know its a            good idea?                                  2002 Alex Chaffee                             ...
How do we know its a     good idea?it works
Learning Ruby via Tests•   [Test-First Teaching](http://testfirst.org)    by Sarah Allen and Alex Chaffee•   [Ruby Koans](h...
Other Guided Learning•   [ruby-warrior](http://github.com/ryanb/ruby-warrior) by Ryan    Bates - a game written in Ruby fo...
Created by:                                              Sarah Allen                                              Alex Cha...
Traditional Professional              Programming Classes                                                 Big, Boring Lect...
writing code is engaging
Methodology•   Run the test•   Watch it fail•   Write code to fix the first failure•   See it pass•   Refactor    Sound fami...
Why TFT?•   makes the assignment very clear•   student gets immediate feedback on progress    (or lack thereof)•   removes...
Embrace Failure
Embrace Failure•   start from a point of failure    •   it feels like its not your fault•   people learn better when theyr...
TFT Example        Lets look at some code
Objects and Methodsrequire "calculator"describe Calculator do  before do    @calculator = Calculator.new  end  it "adds 0 ...
TDD Extra Credit!  # Test-Driving Bonus: once the above tests pass,  # write tests and code for the following:  it "multip...
But...  thatsimpossible
Solutions for Challenging   Idioms        blocks         time   method missing   builder pattern
Blocksrequire "performance_monitor"                                  (and mocks)             it "takes exactly 1 second to...
method_missing, nested       closures, and the builder patternrequire "xml_document"                                      ...
threads               (sorry for the Java)public void testThreadSafe() throws InterruptedException{    int DEPOSITORS = 50...
ruby koans•   self-guided, test-driven•   Ruby language basics•   very fun, whimsical and elegant
ruby koans examplerequire File.expand_path(File.dirname(__FILE__) + /edgecase)class AboutStrings < EdgeCase::Koan  def tes...
TFT != TDD•   Mechanics of testing are hard to learn•   TFT teaches programming; TDD is design•   At the end of some modul...
What about TDD?•   easier to learn TDD, post-TFT    •   know the language    •   know the test framework    •   used to th...
Testing
NOT
Test Driven Development
Design   FocusCollaboration  Testing
TDD
is
Design• You
must
understand
the
problem• The
test
specifies
the
interface
to
the
code  – Having
a
well‐designed
inte...
TDD
helps
you
Focus• Separa>on
of
Development
Phases  – Requirements  – Design  – Implementa>on• Write
all
the
code
you
ne...
TDD
enhances
Collabora>on• Encourages
breakdown
of
complexity• You
know
when
you
are
done• Creates
a
natural
check‐in
poin...
TDD
helps
you
Test• High
quality
tests  – Verifica>on
of
failure
condi>ons
(red,
green)  – Avoid
false
posi>ves• At
the
end...
Alex
Chaffee
Wolfram
Arnold
How
to
start
TDD?• Build
tests
before
refactoring
or
upgrading• Test‐drive
bug
fixes• Write
tests
for
anything
you
worry
ab...
Design   FocusCollaboration  Testing
More Fun!
testfirst.orghttp://github.com/ultrasaurus/test-first-teaching      Many thanks to: Alex Chaffee, Liah Hansen and others
Credits•   Fail Whale illustrated by Yiying Lu (http://    www.yiyinglu.com/)•   Pair Programming photos by Lee Lundrigan ...
Learning should be fun•   Questions?
Test First Teaching and the path to TDD
Test First Teaching and the path to TDD
Upcoming SlideShare
Loading in …5
×

Test First Teaching and the path to TDD

1,481 views

Published on

Test First Teaching background and methodology for teaching programming using automated test frameworks, how this relates to (and can lead to learning) test-driven development

Published in: Technology
  • Be the first to comment

Test First Teaching and the path to TDD

  1. 1. Test First Teaching and the path to TDD
  2. 2. Who am I?Sarah Allen@ultrasaurus
  3. 3. Why should you care?• you want to improve your Ruby skills• you want to do testing (better)• you have a friend or colleague who wants to learn Ruby• you want to help us improve our materials• by teaching, you learn...
  4. 4. by teaching, you learn...• the best engineers are good teachers• we live and work in collaborative environments• it is not enough to know any single thing well• we must teach in order to effectively produce software
  5. 5. What is Test-First Teaching?• teacher provides microtests• student makes them pass • one test at a time• can be used guided (in classroom) or solo • or with a pair
  6. 6. Pairing Is Teaching
  7. 7. Pairing in the classroom • students learn together and teach each other • each pair can proceed through exercises at their own pace • teacher is freed to wander the room
  8. 8. How do we know its a good idea? 2002 Alex Chaffee jGuru Java curriculum 2005 Mike Clark many Ruby Learning Tests independent 2006 ara.t.howard inventors Ruby Quiz #67 "Metakoans" 2008 Yehuda Katz & Matt Aimonetti Ruby on Rails training and many more...http://www.flickr.com/photos/annais/9335897/sizes/z/
  9. 9. How do we know its a good idea?it works
  10. 10. Learning Ruby via Tests• [Test-First Teaching](http://testfirst.org) by Sarah Allen and Alex Chaffee• [Ruby Koans](http://rubykoans.com) by Jim Weirich and Joe O’Brien• [Metakoans](http://rubyquiz.com/quiz67.html) by ara.t.howard
  11. 11. Other Guided Learning• [ruby-warrior](http://github.com/ryanb/ruby-warrior) by Ryan Bates - a game written in Ruby for learning Ruby• [Try Ruby](http://tryruby.org) runs a Ruby interpreter in your browser, with hints and advice• [Growing OO Software In Ruby](http://www.exampler.com/ blog/2009/12/17/growing-object-oriented-software-in-ruby/) by Brian Marick • Ruby version of [Growing Object-Oriented Software Guided by Tests](http://www.growing-object-oriented- software.com/)
  12. 12. Created by: Sarah Allen Alex Chaffee Liah Hansen and friends Test-First Teaching....http://testfirst.org Maybe we should call it Test-First Learninghttp://github.com/ultrasaurus/test-first-teaching
  13. 13. Traditional Professional Programming Classes Big, Boring Lecture Followed by Exercises • multiple choice • fill in the blanks with words or pseudocode • skeleton code - big program with chunks excised and replaced with comments • large task - soup to nuts without feedback.flickr.com/photos/chasephotography/3890300709/
  14. 14. writing code is engaging
  15. 15. Methodology• Run the test• Watch it fail• Write code to fix the first failure• See it pass• Refactor Sound familiar?
  16. 16. Why TFT?• makes the assignment very clear• student gets immediate feedback on progress (or lack thereof)• removes the magic • leads the student through all the steps to writing the code• teaches student to read errors
  17. 17. Embrace Failure
  18. 18. Embrace Failure• start from a point of failure • it feels like its not your fault• people learn better when theyre not stressed• playfulness enhances learning
  19. 19. TFT Example Lets look at some code
  20. 20. Objects and Methodsrequire "calculator"describe Calculator do before do @calculator = Calculator.new end it "adds 0 and 0" do @calculator.add(0,0).should == 0 end it "adds 2 and 2" do @calculator.add(2,2).should == 4 end it "adds positive numbers" do @calculator.add(2,6).should == 8 end it "subtracts numbers" do @calculator.subtract(10,4).should == 6 endend
  21. 21. TDD Extra Credit! # Test-Driving Bonus: once the above tests pass, # write tests and code for the following: it "multiplies two numbers" it "multiplies an array of numbers" it "raises one number to the power of another number" # http://en.wikipedia.org/wiki/Factorial describe "#factorial" do it "computes the factorial of 0" it "computes the factorial of 1" it "computes the factorial of 2" it "computes the factorial of 5" it "computes the factorial of 10" endend
  22. 22. But... thatsimpossible
  23. 23. Solutions for Challenging Idioms blocks time method missing builder pattern
  24. 24. Blocksrequire "performance_monitor" (and mocks) it "takes exactly 1 second to run a block thatdescribe PerformanceMonitor do sleeps for 1 second (with stubs)" do before do fake_time = 100 @monitor = PerformanceMonitor.new Time.stub!(:now).and_return {fake_time} end @monitor.run do fake_time += 1 it "takes about 0 seconds to run an empty block" do end.should == 1 @monitor.run do end end.should be_close(0, 0.1) end it "runs a block N times" do n = 0 it "takes exactly 0 seconds to run an empty block @monitor.run(4) do(with stubs)" do n += 1 Time.stub!(:now).and_return(100) end @monitor.run do n.should == 4 end.should == 0 end end it "returns the average time, not the total time, it "takes about 1 second to run a block that sleeps when running multiple times" dofor 1 second" do run_times = [8,6,5,7] @monitor.run do run_index = 0 sleep 1 fake_time = 100 end.should be_close(1, 0.1) Time.stub(:now).and_return { fake_time } end @monitor.run(4) do fake_time += run_times[run_index] run_index += 1 end.should == 6 end end
  25. 25. method_missing, nested closures, and the builder patternrequire "xml_document" it "nests several levels" dodescribe XmlDocument do @xml.hello do before do @xml.goodbye do @xml = XmlDocument.new @xml.come_back do end @xml.ok_fine(:be => "that_way") end it "renders an empty tag" do end @xml.hello.should == "<hello/>" end.should == end "<hello><goodbye><come_back><ok_fine be=that_way/ ></come_back></goodbye></hello>" it "renders a tag with attributes" do end @xml.hello(:name => dolly).should == "<helloname=dolly/>" it "indents" do end @xml = XmlDocument.new(true) @xml.hello do it "renders a randomly named tag" do @xml.goodbye do tag_name = (1..8).map{|i| @xml.come_back do(a..z).to_a[rand(26)]}.join @xml.ok_fine(:be => "that_way") @xml.send(tag_name).should == "<#{tag_name}/>" end end end end.should == it "renders block with text inside" do "<hello>n" + @xml.hello do " <goodbye>n" + "dolly" " <come_back>n" + end.should == "<hello>dolly</hello>" " <ok_fine be=that_way/>n" + end " </come_back>n" + " </goodbye>n" + it "nests one level" do "</hello>n" @xml.hello do end @xml.goodbye end end.should == "<hello><goodbye/></hello>" end
  26. 26. threads (sorry for the Java)public void testThreadSafe() throws InterruptedException{ int DEPOSITORS = 50; int AMOUNT = 2; // note: increase this value until it *fails* on your CPU. // Then fix it. int REPS = 25000; Account account = new Account("Joe", 0); Thread[] depositors = new Thread[DEPOSITORS]; for (int i=0; i< DEPOSITORS; ++i) { depositors[i] = new Depositor(account, AMOUNT, REPS); depositors[i].start(); } for (int i=0; i< DEPOSITORS; ++i) { depositors[i].join(); } assertEquals(REPS * DEPOSITORS * AMOUNT, account.getBalance());}
  27. 27. ruby koans• self-guided, test-driven• Ruby language basics• very fun, whimsical and elegant
  28. 28. ruby koans examplerequire File.expand_path(File.dirname(__FILE__) + /edgecase)class AboutStrings < EdgeCase::Koan def test_double_quoted_strings_are_strings string = "Hello, World" usually self- assert_equal __, string.is_a?(String) end contained def test_single_quoted_strings_are_also_strings just tests and fixtures, string = Goodbye, World with no class declaration assert_equal __, string.is_a?(String) end def test_use_single_quotes_to_create_string_with_double_quotes “fill in the string = He said, "Go Away." assert_equal __, string blanks” end technique def test_use_double_quotes_to_create_strings_with_single_quotes string = "Dont" assert_equal __, string end teaching through def test_use_backslash_for_those_hard_cases practice and a = "He said, "Dont"" b = He said, "Dont" challenge assert_equal __, a == b end
  29. 29. TFT != TDD• Mechanics of testing are hard to learn• TFT teaches programming; TDD is design• At the end of some modules, students write their own tests for “extra credit” • doesn’t really flex the creative muscles required for software design
  30. 30. What about TDD?• easier to learn TDD, post-TFT • know the language • know the test framework • used to the rhythm of test-first• study design patterns, or check out [GOOS] (http://www.exampler.com/blog/2009/12/17/ growing-object-oriented-software-in-ruby).
  31. 31. Testing
  32. 32. NOT
  33. 33. Test Driven Development
  34. 34. Design FocusCollaboration Testing
  35. 35. TDD
is
Design• You
must
understand
the
problem• The
test
specifies
the
interface
to
the
code – Having
a
well‐designed
interface
is
o<en
more
 important
than
having
an
efficient
implementa>on• Encourages
modular
design
with
clear
 dependencies
  36. 36. TDD
helps
you
Focus• Separa>on
of
Development
Phases – Requirements – Design – Implementa>on• Write
all
the
code
you
need,
 
 and
none
of
the
code
you
don’t
need.
  37. 37. TDD
enhances
Collabora>on• Encourages
breakdown
of
complexity• You
know
when
you
are
done• Creates
a
natural
check‐in
point: – commit
when
your
tests
pass• Quicker
team
checkpoints.


  38. 38. TDD
helps
you
Test• High
quality
tests – Verifica>on
of
failure
condi>ons
(red,
green) – Avoid
false
posi>ves• At
the
end
of
the
project,
you
have
tests!
  39. 39. Alex
Chaffee
  40. 40. Wolfram
Arnold
  41. 41. How
to
start
TDD?• Build
tests
before
refactoring
or
upgrading• Test‐drive
bug
fixes• Write
tests
for
anything
you
worry
about• Con>nuous
Integra>on
is
essen>al• Remove
unused
(untested)
code
  42. 42. Design FocusCollaboration Testing
  43. 43. More Fun!
  44. 44. testfirst.orghttp://github.com/ultrasaurus/test-first-teaching Many thanks to: Alex Chaffee, Liah Hansen and others
  45. 45. Credits• Fail Whale illustrated by Yiying Lu (http:// www.yiyinglu.com/)• Pair Programming photos by Lee Lundrigan and Sarah Allen• Thank you Flickr and Creative Commons (see slides for attribution)
  46. 46. Learning should be fun• Questions?

×