SlideShare a Scribd company logo
Test First Teaching




Alex Chaffee
@alexch
Sarah Allen
@ultrasaurus
Why should you care?

•   you want to learn Ruby
•   you want to improve your Ruby skills
•   you have a friend or colleague who wants to
    learn Ruby
•   you want to help us improve our materials
•   by teaching, you learn...
No, seriously:
by teaching, you learn!
•   the best engineers are good teachers
•   we live and work in collaborative
    environments
•   it is not enough to know any 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
                                  Who else?
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?
Test First Teaching
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
In a classroom setting,
           do more...
•   Conceptual Overview
•   Experimentation (Play, irb)
•   Live Coding a Real-World Example
•   Simple hands-on exercise
•   Name what they learned
TFT Examples



        Let's look at some code
Arithmetic
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
require "pig_latin"

describe "#translate" do
                                   Strings
  include PigLatinTranslator

  it "should translate a simple word" do
    s = translate("nix")
    s.should == "ixnay"
  end

  it "should translate a word beginning with a vowel" do
    s = translate("apple")
    s.should == "appleay"
  end

  it "should translate a word with two consonants" do
    s = translate("stupid")
    s.should == "upidstay"
  end

  it "should translate two words" do
    s = translate("eat pie")
    s.should == "eatay iepay"
  end

  it "should translate many words" do
    s = translate("the quick brown fox")
    s.should == "ethay ickquay ownbray oxfay"
  end
end
Pig Latin Solution
module PigLatinTranslator
  def translate(s)
    s.split.map do |word|
      v = first_vowel(word)
      word.slice(v..-1) + word[0,v] + "ay"
    end.join(" ")
  end

  def first_vowel(word)
    if word =~ /^qu/
      2
    else
      word.gsub(/[aeiou].*$/, '').size
    end
  end
end
Another
          Pig Latin Solution
module PigLatinTranslator
  def translate(s)
    words = s.split
      s = words.map do |s|
      l = s.length
        if /^[aeiou]/ .match(s)
            s + "ay"
        elsif /^qu/ .match(s[0..1])
             s[2..(l+1)] + s[0..1] + "ay"
        elsif /[aeiou]/ .match(s[1..1])
             s[1..(l+1)] + s[0..0] + "ay"
        else
             s[2..(l+1)] + s[0..1] + "ay"
        end
      end
      s = s.join(" ")
  end
end
And Another
             Pig Latin Solution
module PigLatinTranslator
  def translate(word)
    words = word.split(" ")
    arrResult = []
    words.each do |word|
      m = word.match(/^(qu)*[^aeiou]*/)
      if(m.nil?)
        arrResult << add_ay(word)
      else
        arrResult << add_ay(m.post_match + m.to_s)
      end
    end
    arrResult.join(" ")
  end

  def add_ay(word)
    word + "ay"
  end
end
Iterators
describe Calculator do

  before do
    @calculator = Calculator.new
  end

  describe "#sum" do
    it "computes the sum of an empty array" do
      @calculator.sum([]).should == 0
    end

    it "computes the sum of an array of one number" do
      @calculator.sum([7]).should == 7
    end

    it "computes the sum of an array of two numbers" do
      @calculator.sum([7,11]).should == 18
    end

    it "computes the sum of an array of many numbers" do
      @calculator.sum([1,3,5,7,9]).should == 25
    end
  end
Iterators
require "array_extension"

describe Array do

  describe "#sum" do
    it "should be 0 for an empty array" do
      [].sum.should == 0
    end

    it "should add all of the elements" do
      [1,2,4].sum.should == 7
    end
  end

end


            (and open classes)
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).
Credits
•   Mr. Clean® is a registered trademark of Procter &
    Gamble, used without permission
    •   Parody is fair use!
•   Fail Whale illustrated by Yiying Lu (http://
    www.yiyinglu.com/)
•   Pair Programming photos by Lee Lundrigan
•   Thank you Flickr and Creative Commons
    (see slides for attribution)
Sarah

Blazing Cloud
Alex
          alexch.github.com
          @alexch
Erector

Moodlog

Cohuman

 Wrong
Learning should be fun

•   Questions?

More Related Content

What's hot (20)

PDF
Ruby Performance - The Last Mile - RubyConf India 2016
Charles Nutter
 
KEY
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Charles Nutter
 
KEY
JavaOne 2011 - JVM Bytecode for Dummies
Charles Nutter
 
KEY
Static or Dynamic Typing? Why not both?
Mario Camou Riveroll
 
KEY
JavaOne 2012 - JVM JIT for Dummies
Charles Nutter
 
PDF
Oscon Java Testing on the Fast Lane
Andres Almiray
 
PPTX
Mastering java bytecode with ASM - GeeCON 2012
Anton Arhipov
 
PDF
Atlassian Groovy Plugins
Paul King
 
PDF
Pg py-and-squid-pypgday
PostgreSQL Experts, Inc.
 
PDF
JRuby 9000 - Optimizing Above the JVM
Charles Nutter
 
PDF
The Ring programming language version 1.7 book - Part 43 of 196
Mahmoud Samir Fayed
 
PPT
2007 09 10 Fzi Training Groovy Grails V Ws
loffenauer
 
PPT
Mastering Java ByteCode
Ecommerce Solution Provider SysIQ
 
PDF
Real world gobbledygook
Pawel Szulc
 
PDF
Why GC is eating all my CPU?
Roman Elizarov
 
PDF
Who go Types in my Systems Programing!
Jared Roesch
 
KEY
Django’s nasal passage
Erik Rose
 
KEY
Do more than one thing at the same time, the Python way
Jaime Buelta
 
KEY
DjangoCon US 2011 - Monkeying around at New Relic
Graham Dumpleton
 
PDF
JavaScript Patterns
Stoyan Stefanov
 
Ruby Performance - The Last Mile - RubyConf India 2016
Charles Nutter
 
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Charles Nutter
 
JavaOne 2011 - JVM Bytecode for Dummies
Charles Nutter
 
Static or Dynamic Typing? Why not both?
Mario Camou Riveroll
 
JavaOne 2012 - JVM JIT for Dummies
Charles Nutter
 
Oscon Java Testing on the Fast Lane
Andres Almiray
 
Mastering java bytecode with ASM - GeeCON 2012
Anton Arhipov
 
Atlassian Groovy Plugins
Paul King
 
Pg py-and-squid-pypgday
PostgreSQL Experts, Inc.
 
JRuby 9000 - Optimizing Above the JVM
Charles Nutter
 
The Ring programming language version 1.7 book - Part 43 of 196
Mahmoud Samir Fayed
 
2007 09 10 Fzi Training Groovy Grails V Ws
loffenauer
 
Mastering Java ByteCode
Ecommerce Solution Provider SysIQ
 
Real world gobbledygook
Pawel Szulc
 
Why GC is eating all my CPU?
Roman Elizarov
 
Who go Types in my Systems Programing!
Jared Roesch
 
Django’s nasal passage
Erik Rose
 
Do more than one thing at the same time, the Python way
Jaime Buelta
 
DjangoCon US 2011 - Monkeying around at New Relic
Graham Dumpleton
 
JavaScript Patterns
Stoyan Stefanov
 

Similar to Test First Teaching (20)

PDF
Ruby & Machine Vision - Talk at Sheffield Hallam University Feb 2009
Jan Wedekind
 
PPTX
Ruby -the wheel Technology
ppparthpatel123
 
PDF
Functional programming in ruby
Koen Handekyn
 
KEY
Lecture on Rubinius for Compiler Construction at University of Twente
Dirkjan Bussink
 
PPTX
Intro to ruby
Heather Campbell
 
PDF
Ruby — An introduction
Gonçalo Silva
 
PDF
Metaprogramming in Ruby
John Vlachoyiannis
 
PDF
ruby1_6up
tutorialsruby
 
PDF
ruby1_6up
tutorialsruby
 
PDF
DZone%20-%20Essential%20Ruby
tutorialsruby
 
PDF
DZone%20-%20Essential%20Ruby
tutorialsruby
 
KEY
An introduction to Ruby
Wes Oldenbeuving
 
KEY
Tdd for BT E2E test community
Kerry Buckley
 
PDF
Write Your Own JVM Compiler
Erin Dees
 
KEY
Ruby
Kerry Buckley
 
PDF
Test-Tutorial
tutorialsruby
 
PDF
Test-Tutorial
tutorialsruby
 
PDF
The Well-Grounded Nuby
David Black
 
PDF
Piccolo coding dojo (milano xpug 2013-04-11)
Andrea Francia
 
Ruby & Machine Vision - Talk at Sheffield Hallam University Feb 2009
Jan Wedekind
 
Ruby -the wheel Technology
ppparthpatel123
 
Functional programming in ruby
Koen Handekyn
 
Lecture on Rubinius for Compiler Construction at University of Twente
Dirkjan Bussink
 
Intro to ruby
Heather Campbell
 
Ruby — An introduction
Gonçalo Silva
 
Metaprogramming in Ruby
John Vlachoyiannis
 
ruby1_6up
tutorialsruby
 
ruby1_6up
tutorialsruby
 
DZone%20-%20Essential%20Ruby
tutorialsruby
 
DZone%20-%20Essential%20Ruby
tutorialsruby
 
An introduction to Ruby
Wes Oldenbeuving
 
Tdd for BT E2E test community
Kerry Buckley
 
Write Your Own JVM Compiler
Erin Dees
 
Test-Tutorial
tutorialsruby
 
Test-Tutorial
tutorialsruby
 
The Well-Grounded Nuby
David Black
 
Piccolo coding dojo (milano xpug 2013-04-11)
Andrea Francia
 
Ad

More from Sarah Allen (20)

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

Recently uploaded (20)

PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
PDF
July Patch Tuesday
Ivanti
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PPTX
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
July Patch Tuesday
Ivanti
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 

Test First Teaching

  • 1. Test First Teaching Alex Chaffee @alexch Sarah Allen @ultrasaurus
  • 2. Why should you care? • you want to learn Ruby • you want to improve your Ruby skills • you have a friend or colleague who wants to learn Ruby • you want to help us improve our materials • by teaching, you learn...
  • 3. No, seriously: by teaching, you learn! • the best engineers are good teachers • we live and work in collaborative environments • it is not enough to know any thing well • we must teach in order to effectively produce software
  • 4. What is Test-First Teaching? • teacher provides microtests • student makes them pass • one test at a time • can be used guided (in classroom) or solo • or with a pair
  • 6. 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
  • 7. 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 Who else? http://www.flickr.com/photos/annais/9335897/sizes/z/
  • 8. How do we know it's a good idea? it works
  • 9. 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
  • 10. 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/)
  • 11. 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
  • 12. 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/
  • 13. writing code is engaging
  • 14. Methodology • Run the test • Watch it fail • Write code to fix the first failure • See it pass • Refactor Sound familiar?
  • 16. Why TFT? • makes the assignment very clear • student gets immediate feedback on progress (or lack thereof) • removes the magic • leads the student through all the steps to writing the code • teaches student to read errors
  • 18. 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
  • 19. In a classroom setting, do more... • Conceptual Overview • Experimentation (Play, irb) • Live Coding a Real-World Example • Simple hands-on exercise • Name what they learned
  • 20. TFT Examples Let's look at some code
  • 21. Arithmetic 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. require "pig_latin" describe "#translate" do Strings include PigLatinTranslator it "should translate a simple word" do s = translate("nix") s.should == "ixnay" end it "should translate a word beginning with a vowel" do s = translate("apple") s.should == "appleay" end it "should translate a word with two consonants" do s = translate("stupid") s.should == "upidstay" end it "should translate two words" do s = translate("eat pie") s.should == "eatay iepay" end it "should translate many words" do s = translate("the quick brown fox") s.should == "ethay ickquay ownbray oxfay" end end
  • 24. Pig Latin Solution module PigLatinTranslator def translate(s) s.split.map do |word| v = first_vowel(word) word.slice(v..-1) + word[0,v] + "ay" end.join(" ") end def first_vowel(word) if word =~ /^qu/ 2 else word.gsub(/[aeiou].*$/, '').size end end end
  • 25. Another Pig Latin Solution module PigLatinTranslator def translate(s) words = s.split s = words.map do |s| l = s.length if /^[aeiou]/ .match(s) s + "ay" elsif /^qu/ .match(s[0..1]) s[2..(l+1)] + s[0..1] + "ay" elsif /[aeiou]/ .match(s[1..1]) s[1..(l+1)] + s[0..0] + "ay" else s[2..(l+1)] + s[0..1] + "ay" end end s = s.join(" ") end end
  • 26. And Another Pig Latin Solution module PigLatinTranslator def translate(word) words = word.split(" ") arrResult = [] words.each do |word| m = word.match(/^(qu)*[^aeiou]*/) if(m.nil?) arrResult << add_ay(word) else arrResult << add_ay(m.post_match + m.to_s) end end arrResult.join(" ") end def add_ay(word) word + "ay" end end
  • 27. Iterators describe Calculator do before do @calculator = Calculator.new end describe "#sum" do it "computes the sum of an empty array" do @calculator.sum([]).should == 0 end it "computes the sum of an array of one number" do @calculator.sum([7]).should == 7 end it "computes the sum of an array of two numbers" do @calculator.sum([7,11]).should == 18 end it "computes the sum of an array of many numbers" do @calculator.sum([1,3,5,7,9]).should == 25 end end
  • 28. Iterators require "array_extension" describe Array do describe "#sum" do it "should be 0 for an empty array" do [].sum.should == 0 end it "should add all of the elements" do [1,2,4].sum.should == 7 end end end (and open classes)
  • 29. 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
  • 31. Solutions for Challenging Idioms blocks time method missing builder pattern
  • 32. 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
  • 33. 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
  • 34. 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()); }
  • 35. ruby koans • self-guided, test-driven • Ruby language basics • very fun, whimsical and elegant
  • 36. 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
  • 37. 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
  • 38. 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).
  • 39. Credits • Mr. Clean® is a registered trademark of Procter & Gamble, used without permission • Parody is fair use! • Fail Whale illustrated by Yiying Lu (http:// www.yiyinglu.com/) • Pair Programming photos by Lee Lundrigan • Thank you Flickr and Creative Commons (see slides for attribution)
  • 41. Alex alexch.github.com @alexch Erector Moodlog Cohuman Wrong
  • 42. Learning should be fun • Questions?

Editor's Notes

  • #36: TFT is not sufficient for learning, but needs to be one component of a curriculum or course of self-study.