SlideShare a Scribd company logo
Test First Teaching
 and the path to TDD
Who am I?


Sarah Allen
@ultrasaurus
Test First Teaching and the path to TDD
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 it's 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 it's 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 Learning
http://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 it's not your fault
•   people learn better when they're not stressed
•   playfulness enhances learning
TFT Example



        Let's look at some code
Objects and Methods
require "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
  end
end
Test First Teaching and the path to TDD
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"
  end

end
But...
  that's
impossible
Solutions for
 Challenging
   Idioms
        blocks
         time
   method missing
   builder pattern
Blocks
require "performance_monitor"
                                  (and mocks)             it "takes exactly 1 second to run a block that
describe 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" do
for 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 pattern
require "xml_document"
                                                       it "nests several levels" do
describe 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 == "<hello
name='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 example
require 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 = "Don't"
    assert_equal __, string
  end
                                                                    teaching through
  def test_use_backslash_for_those_hard_cases                       practice and
    a = "He said, "Don't""
    b = 'He said, "Don't"'                                         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

   Focus

Collaboration

  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

   Focus

Collaboration

  Testing
More Fun!
testfirst.org

http://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?

More Related Content

KEY
Test First Teaching
PDF
Everything is Permitted: Extending Built-ins
PDF
Fast as C: How to Write Really Terrible Java
PDF
Beyond JVM - YOW! Sydney 2013
PDF
Down the Rabbit Hole
PDF
JVM for Dummies - OSCON 2011
PDF
Down the Rabbit Hole: An Adventure in JVM Wonderland
Test First Teaching
Everything is Permitted: Extending Built-ins
Fast as C: How to Write Really Terrible Java
Beyond JVM - YOW! Sydney 2013
Down the Rabbit Hole
JVM for Dummies - OSCON 2011
Down the Rabbit Hole: An Adventure in JVM Wonderland

What's hot (20)

PPTX
Art of Javascript
PDF
Scalable JavaScript Design Patterns
KEY
JavaOne 2011 - JVM Bytecode for Dummies
PDF
JRuby and Invokedynamic - Japan JUG 2015
PDF
Intro to io
PDF
Oscon Java Testing on the Fast Lane
PPTX
Java 104
PPTX
5 Tips for Better JavaScript
ODP
Perl Teach-In (part 2)
PDF
Taking the boilerplate out of your tests with Sourcery
PDF
Proxies are Awesome!
PPTX
Java 101
PPTX
Awesomeness of JavaScript…almost
PDF
iPhone Memory Management
PDF
Why (I think) CoffeeScript Is Awesome
PDF
Automating Django Functional Tests Using Selenium on Cloud
PDF
Future-proofing Your JavaScript Apps (Compact edition)
PDF
4java Basic Syntax
PPT
Mastering Java ByteCode
PDF
Ruby Performance - The Last Mile - RubyConf India 2016
Art of Javascript
Scalable JavaScript Design Patterns
JavaOne 2011 - JVM Bytecode for Dummies
JRuby and Invokedynamic - Japan JUG 2015
Intro to io
Oscon Java Testing on the Fast Lane
Java 104
5 Tips for Better JavaScript
Perl Teach-In (part 2)
Taking the boilerplate out of your tests with Sourcery
Proxies are Awesome!
Java 101
Awesomeness of JavaScript…almost
iPhone Memory Management
Why (I think) CoffeeScript Is Awesome
Automating Django Functional Tests Using Selenium on Cloud
Future-proofing Your JavaScript Apps (Compact edition)
4java Basic Syntax
Mastering Java ByteCode
Ruby Performance - The Last Mile - RubyConf India 2016
Ad

Similar to Test First Teaching and the path to TDD (20)

KEY
Lecture on Rubinius for Compiler Construction at University of Twente
PDF
Ruby & Machine Vision - Talk at Sheffield Hallam University Feb 2009
PDF
Testing survival Guide
KEY
PDF
The Well-Grounded Nuby
PDF
DZone%20-%20Essential%20Ruby
PDF
DZone%20-%20Essential%20Ruby
PDF
Ruby — An introduction
KEY
Tdd for BT E2E test community
PDF
Piccolo coding dojo (milano xpug 2013-04-11)
PDF
A Gentle Introduction to Functional Paradigms in Ruby
PDF
BDD style Unit Testing
KEY
Advanced Testing on RubyEnRails '09
KEY
An introduction to Ruby
PPTX
Ruby -the wheel Technology
PDF
Why Every Tester Should Learn Ruby
PDF
KEY
Taking a Test Drive: iOS Dev UK guide to TDD
PDF
Blocks and loops.pptx
PDF
Metaprogramming in Ruby
Lecture on Rubinius for Compiler Construction at University of Twente
Ruby & Machine Vision - Talk at Sheffield Hallam University Feb 2009
Testing survival Guide
The Well-Grounded Nuby
DZone%20-%20Essential%20Ruby
DZone%20-%20Essential%20Ruby
Ruby — An introduction
Tdd for BT E2E test community
Piccolo coding dojo (milano xpug 2013-04-11)
A Gentle Introduction to Functional Paradigms in Ruby
BDD style Unit Testing
Advanced Testing on RubyEnRails '09
An introduction to Ruby
Ruby -the wheel Technology
Why Every Tester Should Learn Ruby
Taking a Test Drive: iOS Dev UK guide to TDD
Blocks and loops.pptx
Metaprogramming in Ruby
Ad

More from Sarah Allen (20)

PDF
Internet security: a landscape of unintended consequences
PPTX
RTMP: how did we get to now? (Demuxed 2019)
PDF
Communication is a Technical Skill
PPTX
Improving Federal Government Services
PPTX
Transparency Wins
PPTX
A Short History of Computers
PPTX
Making Software Fun
PPTX
Power of Transparency
PPTX
Designing for Fun
PDF
Ruby in the US Government for Ruby World Conference
PDF
Identities of Dead People
PDF
Let's pretend
PDF
3 Reasons Not to Use Ruby
PDF
Ruby Nation: Why no haz Ruby?
PDF
Why no ruby in gov?
PDF
People Patterns or What I learned from Toastmasters
PDF
Blazing Cloud: Agile Product Development
PDF
Crowdsourced Transcription Landscape
PDF
Lessons Learned Future Thoughts
PDF
Mobile Web Video
Internet security: a landscape of unintended consequences
RTMP: how did we get to now? (Demuxed 2019)
Communication is a Technical Skill
Improving Federal Government Services
Transparency Wins
A Short History of Computers
Making Software Fun
Power of Transparency
Designing for Fun
Ruby in the US Government for Ruby World Conference
Identities of Dead People
Let's pretend
3 Reasons Not to Use Ruby
Ruby Nation: Why no haz Ruby?
Why no ruby in gov?
People Patterns or What I learned from Toastmasters
Blazing Cloud: Agile Product Development
Crowdsourced Transcription Landscape
Lessons Learned Future Thoughts
Mobile Web Video

Recently uploaded (20)

PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Empathic Computing: Creating Shared Understanding
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
cuic standard and advanced reporting.pdf
PPT
Teaching material agriculture food technology
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
sap open course for s4hana steps from ECC to s4
PPTX
Spectroscopy.pptx food analysis technology
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Unlocking AI with Model Context Protocol (MCP)
Reach Out and Touch Someone: Haptics and Empathic Computing
Digital-Transformation-Roadmap-for-Companies.pptx
Empathic Computing: Creating Shared Understanding
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
cuic standard and advanced reporting.pdf
Teaching material agriculture food technology
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Building Integrated photovoltaic BIPV_UPV.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
sap open course for s4hana steps from ECC to s4
Spectroscopy.pptx food analysis technology
The Rise and Fall of 3GPP – Time for a Sabbatical?
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf

Test First Teaching and the path to TDD

  • 1. Test First Teaching and the path to TDD
  • 2. Who am I? Sarah Allen @ultrasaurus
  • 4. 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...
  • 5. 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
  • 6. 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
  • 8. 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
  • 9. How do we know it's 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/
  • 10. How do we know it's a good idea? it works
  • 11. 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
  • 12. 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/)
  • 13. Created by: Sarah Allen Alex Chaffee Liah Hansen and friends Test-First Teaching.... http://testfirst.org Maybe we should call it Test-First Learning http://github.com/ultrasaurus/test-first-teaching
  • 14. 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/
  • 15. writing code is engaging
  • 16. Methodology • Run the test • Watch it fail • Write code to fix the first failure • See it pass • Refactor Sound familiar?
  • 17. 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
  • 19. Embrace Failure • start from a point of failure • it feels like it's not your fault • people learn better when they're not stressed • playfulness enhances learning
  • 20. TFT Example Let's look at some code
  • 21. Objects and Methods require "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 end end
  • 23. 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" end end
  • 25. Solutions for Challenging Idioms blocks time method missing builder pattern
  • 26. Blocks require "performance_monitor" (and mocks) it "takes exactly 1 second to run a block that describe 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" do for 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
  • 27. method_missing, nested closures, and the builder pattern require "xml_document" it "nests several levels" do describe 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 == "<hello name='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
  • 28. 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()); }
  • 29. ruby koans • self-guided, test-driven • Ruby language basics • very fun, whimsical and elegant
  • 30. ruby koans example require 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 = "Don't" assert_equal __, string end teaching through def test_use_backslash_for_those_hard_cases practice and a = "He said, "Don't"" b = 'He said, "Don't"' challenge assert_equal __, a == b end
  • 31. 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
  • 32. 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).
  • 34. NOT
  • 36. Design Focus Collaboration Testing
  • 37. 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
  • 38. 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.
  • 39. 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.


  • 40. 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!
  • 43. 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
  • 44. Design Focus Collaboration Testing
  • 46. testfirst.org http://github.com/ultrasaurus/test-first-teaching Many thanks to: Alex Chaffee, Liah Hansen and others
  • 47. 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)
  • 48. Learning should be fun • Questions?

Editor's Notes

  • #2: \n
  • #3: \n
  • #4: \n
  • #5: \n
  • #6: \n
  • #7: \n
  • #8: \n
  • #9: \n
  • #10: \n
  • #11: \n
  • #12: \n
  • #13: \n
  • #14: \n
  • #15: \n
  • #16: \n
  • #17: \n
  • #18: \n
  • #19: \n
  • #20: \n
  • #21: \n
  • #22: \n
  • #23: \n
  • #24: \n
  • #25: \n
  • #26: \n
  • #27: \n
  • #28: \n
  • #29: \n
  • #30: TFT is not sufficient for learning, but needs to be one component of a curriculum or course of self-study.\n
  • #31: \n
  • #32: \n
  • #33: \n
  • #34: \n
  • #35: \n
  • #36: \n
  • #37: \n
  • #38: \n
  • #39: 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
  • #40: \n
  • #41: High quality tests:&amp;#xA0;Writing test first... you know they fail in the way you expect them to fail. &amp;#xA0;Test last means that your tests will pass, which is occasionally a false positive. &amp;#xA0;(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
  • #42: \n
  • #43: \n
  • #44: \n
  • #45: \n
  • #46: \n
  • #47: \n
  • #48: \n
  • #49: \n