• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Test First Teaching and the path to TDD
 

Test First Teaching and the path to TDD

on

  • 1,033 views

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

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

Statistics

Views

Total Views
1,033
Views on SlideShare
1,033
Embed Views
0

Actions

Likes
0
Downloads
11
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • TFT is not sufficient for learning, but needs to be one component of a curriculum or course of self-study.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • If you apply a tight cycle of write one test, then write the code to implement that test, then write the next test, your code ends up growing organically. This often (though not always) leads to less wasted effort.\n
  • \n
  • High quality tests: Writing test first... you know they fail in the way you expect them to fail.  Test last means that your tests will pass, which is occasionally a false positive.  (pretense of test coverage) Writing tests is often seen as a chore; writing the tests first guarantees that at the end of the project you will have written a suite of unit tests (rather than leaving them until the end and possibly never getting around to it).\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Test First Teaching and the path to TDD Test First Teaching and the path to TDD Presentation Transcript

  • 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 colleague who wants to learn Ruby• you want to help us improve our materials• by teaching, you learn...
  • 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
  • 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
  • Pairing Is Teaching
  • 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
  • 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/
  • 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](http://rubykoans.com) by Jim Weirich and Joe O’Brien• [Metakoans](http://rubyquiz.com/quiz67.html) by ara.t.howard
  • 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/)
  • 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
  • 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/
  • writing code is engaging
  • Methodology• Run the test• Watch it fail• Write code to fix the first failure• See it pass• Refactor Sound familiar?
  • 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
  • Embrace Failure
  • 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
  • TFT Example Lets look at some code
  • 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
  • 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
  • But... thatsimpossible
  • Solutions for Challenging Idioms blocks time method missing builder pattern
  • 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
  • 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
  • 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());}
  • 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 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
  • 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
  • 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).
  • 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
interface
is
o<en
more
 important
than
having
an
efficient
implementa>on• Encourages
modular
design
with
clear
 dependencies
  • 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.
  • 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.


  • 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!
  • Alex
Chaffee
  • Wolfram
Arnold
  • 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
  • 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 and Sarah Allen• Thank you Flickr and Creative Commons (see slides for attribution)
  • Learning should be fun• Questions?