Coding with Confidence
    Adding TDD to Your Toolset
image: un-sharp @ flickr
why test?
reduce defects
verify expectations
why test first?
“The metric I, and others I
 know, have used to judge
 unit testing is: does it find
           bugs?”
                    ...
kinda.
“When you write unit
tests ... you scrutinize, you
   think, and often you
prevent problems without
 even encountering a t...
Test-Driven Development
Test-Driven Design
1. Design the API
2. Make it work
3. Make it clean
cohesion
coupling
“As long as you don't change
 that component's external
    interfaces, you can be
 comfortable that you won't
 cause prob...
avoid complicated
solutions to simple
     problems
insurance
image: buttepubliclibrary @ flickr
regressions
mess   image: locket479 @ flickr
“Consider a building with a
few broken windows. If the
 windows are not repaired,
 the tendency is for vandals
  to break ...
fear   image: troyholden @ flickr
“Test-driven
development is a way of
 managing fear during
    programming”
                Kent Beck
documentation




                image: horrgakx @ flickr
1. Design the API
2. Make it work
3. Make it clean
1. Design the API
         write a failing test

2. Make it work
3. Make it clean
1. Design the API
         write a failing test

2. Make it work
         make the test pass

3. Make it clean
1. Design the API
         write a failing test

2. Make it work
         make the test pass

3. Make it clean
         re...
1. RED
2. GREEN
3. REFACTOR



              image: rooreynolds @ flickr
class FabricatedTest < Test::Unit::TestCase

  def setup
    File.touch('tempfile')
  end

  def teardown
    FileUtils.rm...
class FabricatedTest < Test::Unit::TestCase   Test case


  def setup
    File.touch('tempfile')
  end

  def teardown
   ...
class FabricatedTest < Test::Unit::TestCase   Test case


  def setup                                   Test setup
    Fil...
class FabricatedTest < Test::Unit::TestCase   Test case


  def setup                                   Test setup
    Fil...
class FabricatedTest < Test::Unit::TestCase   Test case


  def setup                                   Test setup
    Fil...
class FabricatedTest < Test::Unit::TestCase   Test case


  def setup                                   Test setup
    Fil...
image: mediageek @ flickr
Pitfalls
class User
  attr_accessor :name
end

class UserTest < Test::Unit::TestCase

  def test_should_be_able_to_set_name
    use...
class UserTest < Test::Unit::TestCase

  def test_valid
    user = User.new

      assert !user.valid?

    assert user.er...
class Line

    def initialize(content)
      @content = content
    end

    private
    def extract(pattern)
      @cont...
class UserTest < Test::Unit::TestCase

  def setup
    @content = '{"user_name":"reagent","user_id":"12345"}'
  end

  def...
class User
   attr_writer :name

   def name
     @name.strip
   end
 end

 class UserTest < Test::Unit::TestCase

   def ...
TDD is a tool
TDD is not a religion
Resources
  • Slides / Code: http://github.com/reagent/talks
Contact
  • patrick.reagan@viget.com
  • http://twitter.com/r...
Coding With Confidence: Adding TDD to Your Toolset
Upcoming SlideShare
Loading in...5
×

Coding With Confidence: Adding TDD to Your Toolset

2,264

Published on

Patrick talks about how a test-first strategy has been mistaken as a purely QA activity, and discusses the benefits developers can discover when taking a test-driven approach to developing their code.

Published in: Technology, Business
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,264
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
11
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Coding With Confidence: Adding TDD to Your Toolset

  1. 1. Coding with Confidence Adding TDD to Your Toolset
  2. 2. image: un-sharp @ flickr
  3. 3. why test?
  4. 4. reduce defects
  5. 5. verify expectations
  6. 6. why test first?
  7. 7. “The metric I, and others I know, have used to judge unit testing is: does it find bugs?” Bill Moorier
  8. 8. kinda.
  9. 9. “When you write unit tests ... you scrutinize, you think, and often you prevent problems without even encountering a test failure.” Michael Feathers
  10. 10. Test-Driven Development
  11. 11. Test-Driven Design
  12. 12. 1. Design the API 2. Make it work 3. Make it clean
  13. 13. cohesion coupling
  14. 14. “As long as you don't change that component's external interfaces, you can be comfortable that you won't cause problems that ripple through the entire system” The Pragmatic Programmer
  15. 15. avoid complicated solutions to simple problems
  16. 16. insurance image: buttepubliclibrary @ flickr
  17. 17. regressions
  18. 18. mess image: locket479 @ flickr
  19. 19. “Consider a building with a few broken windows. If the windows are not repaired, the tendency is for vandals to break more windows” The Atlantic Monthly (1982)
  20. 20. fear image: troyholden @ flickr
  21. 21. “Test-driven development is a way of managing fear during programming” Kent Beck
  22. 22. documentation image: horrgakx @ flickr
  23. 23. 1. Design the API 2. Make it work 3. Make it clean
  24. 24. 1. Design the API write a failing test 2. Make it work 3. Make it clean
  25. 25. 1. Design the API write a failing test 2. Make it work make the test pass 3. Make it clean
  26. 26. 1. Design the API write a failing test 2. Make it work make the test pass 3. Make it clean remove duplication
  27. 27. 1. RED 2. GREEN 3. REFACTOR image: rooreynolds @ flickr
  28. 28. class FabricatedTest < Test::Unit::TestCase def setup File.touch('tempfile') end def teardown FileUtils.rm('tempfile') end def test_should_know_the_number_of_items bag = Bag.new(3) assert_equal 3, bag.item_count end end anatomy
  29. 29. class FabricatedTest < Test::Unit::TestCase Test case def setup File.touch('tempfile') end def teardown FileUtils.rm('tempfile') end def test_should_know_the_number_of_items bag = Bag.new(3) assert_equal 3, bag.item_count end end anatomy
  30. 30. class FabricatedTest < Test::Unit::TestCase Test case def setup Test setup File.touch('tempfile') (run every test) end def teardown FileUtils.rm('tempfile') end def test_should_know_the_number_of_items bag = Bag.new(3) assert_equal 3, bag.item_count end end anatomy
  31. 31. class FabricatedTest < Test::Unit::TestCase Test case def setup Test setup File.touch('tempfile') (run every test) end def teardown Test teardown FileUtils.rm('tempfile') (run every test) end def test_should_know_the_number_of_items bag = Bag.new(3) assert_equal 3, bag.item_count end end anatomy
  32. 32. class FabricatedTest < Test::Unit::TestCase Test case def setup Test setup File.touch('tempfile') (run every test) end def teardown Test teardown FileUtils.rm('tempfile') (run every test) end def test_should_know_the_number_of_items Test bag = Bag.new(3) assert_equal 3, bag.item_count end end anatomy
  33. 33. class FabricatedTest < Test::Unit::TestCase Test case def setup Test setup File.touch('tempfile') (run every test) end def teardown Test teardown FileUtils.rm('tempfile') (run every test) end def test_should_know_the_number_of_items Test bag = Bag.new(3) assert_equal 3, bag.item_count Assertion end end anatomy
  34. 34. image: mediageek @ flickr
  35. 35. Pitfalls
  36. 36. class User attr_accessor :name end class UserTest < Test::Unit::TestCase def test_should_be_able_to_set_name user = User.new user.name = 'Patrick' assert_equal 'Patrick', user.name end end testing language features
  37. 37. class UserTest < Test::Unit::TestCase def test_valid user = User.new assert !user.valid? assert user.errors.on(:name) assert user.errors.on(:username) end end multiple assertions
  38. 38. class Line def initialize(content) @content = content end private def extract(pattern) @content.match(pattern)[1] end end class LineTest < Test::Unit::TestCase def test_extract_should_return_captured_value line = Line.new('This is content') assert_equal 'is', line.send(:extract, /(is)/) end end testing private methods
  39. 39. class UserTest < Test::Unit::TestCase def setup @content = '{"user_name":"reagent","user_id":"12345"}' end def test_should_be_able_to_extract_the_username user = User.new(@content) assert_equal 'reagent', user.username end def test_should_be_able_to_extract_the_user_id user = User.new(@content) assert_equal '12345', user.id end end lack of context
  40. 40. class User attr_writer :name def name @name.strip end end class UserTest < Test::Unit::TestCase def test_should_remove_whitespace_from_name user = User.new user.name = ' Patrick ' assert_equal 'Patrick', user.name end end testing the happy path
  41. 41. TDD is a tool
  42. 42. TDD is not a religion
  43. 43. Resources • Slides / Code: http://github.com/reagent/talks Contact • patrick.reagan@viget.com • http://twitter.com/reagent Rate This Talk • http://speakerrate.com/preagan image: nomeacuerdo @ flickr
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×