SlideShare a Scribd company logo
1 of 44
Download to read offline
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?”
                    Bill Moorier
kinda.
“When you write unit
tests ... you scrutinize, you
   think, and often you
prevent problems without
 even encountering a test
            failure.”
                  Michael Feathers
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 problems that ripple
 through the entire system”
           The Pragmatic Programmer
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 more windows”
           The Atlantic Monthly (1982)
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
         remove duplication
1. RED
2. GREEN
3. REFACTOR



              image: rooreynolds @ flickr
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
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
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
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
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
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
image: mediageek @ flickr
Pitfalls
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
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
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
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
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
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/reagent
Rate This Talk
  •   http://speakerrate.com/preagan




                                                     image: nomeacuerdo @ flickr

More Related Content

What's hot

Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
nicobn
 
Smarter Testing with Spock
Smarter Testing with SpockSmarter Testing with Spock
Smarter Testing with Spock
Dmitry Voloshko
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
varuntaliyan
 

What's hot (20)

Spock Framework
Spock FrameworkSpock Framework
Spock Framework
 
Spock framework
Spock frameworkSpock framework
Spock framework
 
Unit testing with Spock Framework
Unit testing with Spock FrameworkUnit testing with Spock Framework
Unit testing with Spock Framework
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step TrainingUnit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
 
Intro to Testing in Zope, Plone
Intro to Testing in Zope, PloneIntro to Testing in Zope, Plone
Intro to Testing in Zope, Plone
 
Linux intro 5 extra: makefiles
Linux intro 5 extra: makefilesLinux intro 5 extra: makefiles
Linux intro 5 extra: makefiles
 
Mock it right! A beginner’s guide to world of tests and mocks, Maciej Polańczyk
Mock it right! A beginner’s guide to world of tests and mocks, Maciej PolańczykMock it right! A beginner’s guide to world of tests and mocks, Maciej Polańczyk
Mock it right! A beginner’s guide to world of tests and mocks, Maciej Polańczyk
 
Smarter Testing with Spock
Smarter Testing with SpockSmarter Testing with Spock
Smarter Testing with Spock
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
 
JUnit
JUnitJUnit
JUnit
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
Double Trouble
Double TroubleDouble Trouble
Double Trouble
 
Unit testing
Unit testingUnit testing
Unit testing
 
PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to hero
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Test Driven Development with PHPUnit
Test Driven Development with PHPUnitTest Driven Development with PHPUnit
Test Driven Development with PHPUnit
 
Python unittest
Python unittestPython unittest
Python unittest
 
PHPUnit
PHPUnitPHPUnit
PHPUnit
 

Viewers also liked (6)

Hows Haml?
Hows Haml?Hows Haml?
Hows Haml?
 
Mockfight! FlexMock vs. Mocha
Mockfight! FlexMock vs. MochaMockfight! FlexMock vs. Mocha
Mockfight! FlexMock vs. Mocha
 
Changing Your Mindset: Getting Started with Test-Driven Development
Changing Your Mindset: Getting Started with Test-Driven DevelopmentChanging Your Mindset: Getting Started with Test-Driven Development
Changing Your Mindset: Getting Started with Test-Driven Development
 
Make Everyone a Tester: Natural Language Acceptance Testing
Make Everyone a Tester: Natural Language Acceptance TestingMake Everyone a Tester: Natural Language Acceptance Testing
Make Everyone a Tester: Natural Language Acceptance Testing
 
Better Functional Design through TDD
Better Functional Design through TDDBetter Functional Design through TDD
Better Functional Design through TDD
 
32 Ways a Digital Marketing Consultant Can Help Grow Your Business
32 Ways a Digital Marketing Consultant Can Help Grow Your Business32 Ways a Digital Marketing Consultant Can Help Grow Your Business
32 Ways a Digital Marketing Consultant Can Help Grow Your Business
 

Similar to Coding With Confidence: Adding TDD to Your Toolset

Testing for Pragmatic People
Testing for Pragmatic PeopleTesting for Pragmatic People
Testing for Pragmatic People
davismr
 
Parameterization is nothing but giving multiple input
Parameterization is nothing but giving multiple inputParameterization is nothing but giving multiple input
Parameterization is nothing but giving multiple input
uanna
 

Similar to Coding With Confidence: Adding TDD to Your Toolset (20)

How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytest
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdf
 
ExtraFileIO.pptx
ExtraFileIO.pptxExtraFileIO.pptx
ExtraFileIO.pptx
 
Python testing
Python  testingPython  testing
Python testing
 
Write codeforhumans
Write codeforhumansWrite codeforhumans
Write codeforhumans
 
Testing for Pragmatic People
Testing for Pragmatic PeopleTesting for Pragmatic People
Testing for Pragmatic People
 
Linux intro 4 awk + makefile
Linux intro 4  awk + makefileLinux intro 4  awk + makefile
Linux intro 4 awk + makefile
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slides
 
Laravel Unit Testing
Laravel Unit TestingLaravel Unit Testing
Laravel Unit Testing
 
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
 
Unit testing presentation
Unit testing presentationUnit testing presentation
Unit testing presentation
 
Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
Presentation Unit Testing process
Presentation Unit Testing processPresentation Unit Testing process
Presentation Unit Testing process
 
Unit testing
Unit testingUnit testing
Unit testing
 
Parameterization is nothing but giving multiple input
Parameterization is nothing but giving multiple inputParameterization is nothing but giving multiple input
Parameterization is nothing but giving multiple input
 
Organizing Machine Learning Projects - Repository Organization
Organizing Machine Learning Projects - Repository OrganizationOrganizing Machine Learning Projects - Repository Organization
Organizing Machine Learning Projects - Repository Organization
 
Python testing using mock and pytest
Python testing using mock and pytestPython testing using mock and pytest
Python testing using mock and pytest
 
Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz Java history, versions, types of errors and exception, quiz
Java history, versions, types of errors and exception, quiz
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governance
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Modernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaModernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using Ballerina
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
 

Coding With Confidence: Adding TDD to Your Toolset

  • 1. Coding with Confidence Adding TDD to Your Toolset
  • 7. “The metric I, and others I know, have used to judge unit testing is: does it find bugs?” Bill Moorier
  • 9. “When you write unit tests ... you scrutinize, you think, and often you prevent problems without even encountering a test failure.” Michael Feathers
  • 12. 1. Design the API 2. Make it work 3. Make it clean
  • 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
  • 18. mess image: locket479 @ flickr
  • 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. fear image: troyholden @ flickr
  • 21. “Test-driven development is a way of managing fear during programming” Kent Beck
  • 22. documentation image: horrgakx @ flickr
  • 23. 1. Design the API 2. Make it work 3. Make it clean
  • 24. 1. Design the API write a failing test 2. Make it work 3. Make it clean
  • 25. 1. Design the API write a failing test 2. Make it work make the test pass 3. Make it clean
  • 26. 1. Design the API write a failing test 2. Make it work make the test pass 3. Make it clean remove duplication
  • 27. 1. RED 2. GREEN 3. REFACTOR image: rooreynolds @ flickr
  • 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. 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. 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. 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. 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. 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
  • 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. 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. 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. 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. 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. TDD is a tool
  • 42. TDD is not a religion
  • 43.
  • 44. 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