Coding With Confidence: Adding TDD to Your Toolset

2,541 views

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,541
On SlideShare
0
From Embeds
0
Number of Embeds
831
Actions
Shares
0
Downloads
12
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

×