SlideShare a Scribd company logo
1 of 48
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 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
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

What's hot

Art of Javascript
Art of JavascriptArt of Javascript
Art of JavascriptTarek Yehia
 
Scalable JavaScript Design Patterns
Scalable JavaScript Design PatternsScalable JavaScript Design Patterns
Scalable JavaScript Design PatternsAddy Osmani
 
JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesCharles Nutter
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015Charles Nutter
 
Oscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast LaneOscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast LaneAndres Almiray
 
5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScriptTodd Anglin
 
Perl Teach-In (part 2)
Perl Teach-In (part 2)Perl Teach-In (part 2)
Perl Teach-In (part 2)Dave Cross
 
Taking the boilerplate out of your tests with Sourcery
Taking the boilerplate out of your tests with SourceryTaking the boilerplate out of your tests with Sourcery
Taking the boilerplate out of your tests with SourceryVincent Pradeilles
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!Brendan Eich
 
Awesomeness of JavaScript…almost
Awesomeness of JavaScript…almostAwesomeness of JavaScript…almost
Awesomeness of JavaScript…almostQuinton Sheppard
 
iPhone Memory Management
iPhone Memory ManagementiPhone Memory Management
iPhone Memory ManagementVadim Zimin
 
Why (I think) CoffeeScript Is Awesome
Why (I think) CoffeeScript Is AwesomeWhy (I think) CoffeeScript Is Awesome
Why (I think) CoffeeScript Is AwesomeJo Cranford
 
Automating Django Functional Tests Using Selenium on Cloud
Automating Django Functional Tests Using Selenium on CloudAutomating Django Functional Tests Using Selenium on Cloud
Automating Django Functional Tests Using Selenium on CloudJonghyun Park
 
Future-proofing Your JavaScript Apps (Compact edition)
Future-proofing Your JavaScript Apps (Compact edition)Future-proofing Your JavaScript Apps (Compact edition)
Future-proofing Your JavaScript Apps (Compact edition)Addy Osmani
 
4java Basic Syntax
4java Basic Syntax4java Basic Syntax
4java Basic SyntaxAdil Jafri
 
Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Charles Nutter
 

What's hot (20)

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

Similar to Test First Teaching and the path to TDD

CBDW2014 - MockBox, get ready to mock your socks off!
CBDW2014 - MockBox, get ready to mock your socks off!CBDW2014 - MockBox, get ready to mock your socks off!
CBDW2014 - MockBox, get ready to mock your socks off!Ortus Solutions, Corp
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# DevelopersCory Foy
 
Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Mario Camou Riveroll
 
Testing in Scala. Adform Research
Testing in Scala. Adform ResearchTesting in Scala. Adform Research
Testing in Scala. Adform ResearchVasil Remeniuk
 
Testing in Scala by Adform research
Testing in Scala by Adform researchTesting in Scala by Adform research
Testing in Scala by Adform researchVasil Remeniuk
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctlyDror Helper
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Leveling Up at JavaScript
Leveling Up at JavaScriptLeveling Up at JavaScript
Leveling Up at JavaScriptRaymond Camden
 
DevDay.lk - Bare Knuckle Web Development
DevDay.lk - Bare Knuckle Web DevelopmentDevDay.lk - Bare Knuckle Web Development
DevDay.lk - Bare Knuckle Web DevelopmentJohannes Brodwall
 
Boost Maintainability
Boost MaintainabilityBoost Maintainability
Boost MaintainabilityMosky Liu
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesTony Nguyen
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesHarry Potter
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesHoang Nguyen
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesYoung Alista
 

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

Ruby
RubyRuby
Ruby
 
Java Tutorial
Java Tutorial Java Tutorial
Java Tutorial
 
CBDW2014 - MockBox, get ready to mock your socks off!
CBDW2014 - MockBox, get ready to mock your socks off!CBDW2014 - MockBox, get ready to mock your socks off!
CBDW2014 - MockBox, get ready to mock your socks off!
 
Conf orm - explain
Conf orm - explainConf orm - explain
Conf orm - explain
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# Developers
 
Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?
 
Ruby basics
Ruby basicsRuby basics
Ruby basics
 
Testing in Scala. Adform Research
Testing in Scala. Adform ResearchTesting in Scala. Adform Research
Testing in Scala. Adform Research
 
Testing in Scala by Adform research
Testing in Scala by Adform researchTesting in Scala by Adform research
Testing in Scala by Adform research
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Leveling Up at JavaScript
Leveling Up at JavaScriptLeveling Up at JavaScript
Leveling Up at JavaScript
 
55 New Features in Java 7
55 New Features in Java 755 New Features in Java 7
55 New Features in Java 7
 
Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance Tuning
 
DevDay.lk - Bare Knuckle Web Development
DevDay.lk - Bare Knuckle Web DevelopmentDevDay.lk - Bare Knuckle Web Development
DevDay.lk - Bare Knuckle Web Development
 
Boost Maintainability
Boost MaintainabilityBoost Maintainability
Boost Maintainability
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 

More from Sarah Allen

Internet security: a landscape of unintended consequences
Internet security: a landscape of unintended consequencesInternet security: a landscape of unintended consequences
Internet security: a landscape of unintended consequencesSarah Allen
 
RTMP: how did we get to now? (Demuxed 2019)
RTMP: how did we get to now? (Demuxed 2019)RTMP: how did we get to now? (Demuxed 2019)
RTMP: how did we get to now? (Demuxed 2019)Sarah Allen
 
Communication is a Technical Skill
Communication is a Technical SkillCommunication is a Technical Skill
Communication is a Technical SkillSarah Allen
 
Improving Federal Government Services
Improving Federal Government ServicesImproving Federal Government Services
Improving Federal Government ServicesSarah Allen
 
Transparency Wins
Transparency WinsTransparency Wins
Transparency WinsSarah Allen
 
A Short History of Computers
A Short History of ComputersA Short History of Computers
A Short History of ComputersSarah Allen
 
Making Software Fun
Making Software FunMaking Software Fun
Making Software FunSarah Allen
 
Power of Transparency
Power of TransparencyPower of Transparency
Power of TransparencySarah Allen
 
Designing for Fun
Designing for FunDesigning for Fun
Designing for FunSarah Allen
 
Ruby in the US Government for Ruby World Conference
Ruby in the US Government for Ruby World ConferenceRuby in the US Government for Ruby World Conference
Ruby in the US Government for Ruby World ConferenceSarah Allen
 
Identities of Dead People
Identities of Dead PeopleIdentities of Dead People
Identities of Dead PeopleSarah Allen
 
3 Reasons Not to Use Ruby
3 Reasons Not to Use Ruby 3 Reasons Not to Use Ruby
3 Reasons Not to Use Ruby Sarah Allen
 
Ruby Nation: Why no haz Ruby?
Ruby Nation: Why no haz Ruby?Ruby Nation: Why no haz Ruby?
Ruby Nation: Why no haz Ruby?Sarah Allen
 
Why no ruby in gov?
Why no ruby in gov?Why no ruby in gov?
Why no ruby in gov?Sarah Allen
 
People Patterns or What I learned from Toastmasters
People Patterns or What I learned from ToastmastersPeople Patterns or What I learned from Toastmasters
People Patterns or What I learned from ToastmastersSarah Allen
 
Blazing Cloud: Agile Product Development
Blazing Cloud: Agile Product DevelopmentBlazing Cloud: Agile Product Development
Blazing Cloud: Agile Product DevelopmentSarah Allen
 
Crowdsourced Transcription Landscape
Crowdsourced Transcription LandscapeCrowdsourced Transcription Landscape
Crowdsourced Transcription LandscapeSarah Allen
 
Lessons Learned Future Thoughts
Lessons Learned Future ThoughtsLessons Learned Future Thoughts
Lessons Learned Future ThoughtsSarah Allen
 
Mobile Web Video
Mobile Web VideoMobile Web Video
Mobile Web VideoSarah Allen
 

More from Sarah Allen (20)

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

Recently uploaded

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 

Recently uploaded (20)

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 

Test First Teaching and the path to TDD

  • 1. Test First Teaching and the path to TDD
  • 2. Who am I? Sarah Allen @ultrasaurus
  • 3.
  • 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
  • 22.
  • 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

  1. \n
  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. TFT is not sufficient for learning, but needs to be one component of a curriculum or course of self-study.\n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. 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
  39. \n
  40. 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
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n