Your SlideShare is downloading. ×
0
Changing Your Mindset
Getting Started With Test-Driven Development
Patrick Reagan
Director, Application Development
patric...
Overview
  Testing Process
  Test::Unit Introduction
  Code Example: GoogleRank
  Testing Pitfalls
  Coverage Analysi...
Test-Driven Development is the
          process of testing the behavior of
                non-existent objects




Chang...
Testing Cycle

                                                  Write
                                               Fail...
Why Test First?

  No untested code is written
  Start with higher code coverage
  Rapid feedback
  Build your regress...
Anatomy of a (Test::Unit) Test Case

                                               Test case

                           ...
Naming Conventions



        Method to test


                                Parameters / Input


                      ...
Basic Assertions
         assert


         assert_equal / assert_not_equal

         assert_nil / assert_not_nil


  ...
Code Example
 Class that retrieves Google results
              Retrieves only the top 10 URLs
              URL encodes...
Start Small




 test_google_rank_should_exist(GoogleRankTest):
 Exception raised: Class: <NameError>
 Message: <"uninitia...
Simplest Thing That Works

                                                          Class method

 test_parse_with_empty_...
Simplest Thing That Actually Works




  2 tests, 1 assertions, 0 failures, 0 errors




Changing Your Mindset
Getting Sta...
Use a Canned Data Set

                                                                Sample markup
                     ...
Use a Canned Data Set




1 tests, 1 assertions, 0 failures, 0 errors




Changing Your Mindset
Getting Started With Test-...
Running Regressions
  test_parse_with_empty_document_should_return_empty_array(GoogleRankTest):
  NoMethodError: undefined...
Fix Regressions




 3 tests, 2 assertions, 0 failures, 0 errors




Changing Your Mindset
Getting Started With Test-Drive...
Code Example
 Class that retrieves Google results
              Retrieves only the top 10 URLs
              URL encodes...
Retrieve Internal State




                                      Inspect instance variable

NameError: uninitialized cons...
Retrieve Internal State




test_new_should_encode_supplied_keywords(GoogleRankTest):
ArgumentError: wrong number of argum...
Retrieve Internal State




1 tests, 1 assertions, 0 failures, 0 errors


4 tests, 3 assertions, 0 failures, 0 errors




...
Refactor Test Duplication




4 tests, 3 assertions, 0 failures, 0 errors




Changing Your Mindset
Getting Started With T...
Testing Encoding




test_new_should_assign_url_with_base_and_encoded_keywords(GoogleRankTest):
NameError: uninitialized c...
Testing Encoding




1 tests, 1 assertions, 0 failures, 0 errors


5 tests, 4 assertions, 0 failures, 0 errors


Changing ...
Code Example
 Class that retrieves Google results
              Retrieves only the top 10 URLs
              URL encodes...
“Mock objects are simulated
       objects that mimic the behavior of
       real objects in controlled ways”
            ...
Mocks and Stubs

  Remove external dependencies
  Create known state
  Focus tests on specific code paths




Changing ...
Mocha to Stub Net::HTTP



                                                        Implementation will use
               ...
Mocha to Stub Net::HTTP




6 tests, 5 assertions, 0 failures, 0 errors



Changing Your Mindset
Getting Started With Test...
No Network? Oops!



  $ irb --prompt simple
  >> gr = GoogleRank.new('rails')
  => #<GoogleRank:0x54c89c @encoded_keyword...
Replicate Real-Word Conditions


                                                         Expected failure




test_retrie...
Dealing With Failure




7 tests, 6 assertions, 0 failures, 0 errors




Changing Your Mindset
Getting Started With Test-D...
Code Example
 Class that retrieves Google results
              Retrieves only the top 10 URLs
              URL encodes...
Dealing With Even More Failure




test_retrieve_content_when_connection_fails_should_raise_exception_and_set_content_to_n...
Handling Unsuccessful Requests




8 tests, 8 assertions, 0 failures, 0 errors


Changing Your Mindset
Getting Started Wit...
Testing Pitfalls

 Things to avoid
              Over-mocking
              Invalid mocks
              Testing library...
Testing Pitfalls



                                                     Should test parsing




                         ...
Testing Pitfalls


                                               Use secondary test
                                     ...
Coverage Analysis


  Shows ‘tested’ code
  Indication of when to stop
  Can present a false impression




Changing Yo...
Coverage With RCov




                                               Exception-prone




Changing Your Mindset
Getting St...
Next Steps?

  Rake - Rake::TestTask
  Mock expectations as tests
  Testing Macros




Changing Your Mindset
Getting St...
Rake::TestTask Example




 $ rake -T
 rake test:all           # Run tests for all




Changing Your Mindset
Getting Start...
Expectations as Tests




                                               attr_accessor :content
                          ...
Testing Macros




Changing Your Mindset
Getting Started With Test-Driven Development
September 7th, 2007
Resources
 Test::Unit
          http://ruby-doc.org/stdlib
 Mocha
          http://mocha.rubyforge.org
 RCov
          ...
Slides
                         http://www.slideshare.net/viget

                                                Blog
    ...
Upcoming SlideShare
Loading in...5
×

Changing Your Mindset: Getting Started with Test-Driven Development

760

Published on

Patrick Reagan gives an introduction to the process of Test-Driven development in Ruby.

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

No Downloads
Views
Total Views
760
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
13
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Transcript of "Changing Your Mindset: Getting Started with Test-Driven Development"

  1. 1. Changing Your Mindset Getting Started With Test-Driven Development Patrick Reagan Director, Application Development patrick@viget.com
  2. 2. Overview  Testing Process  Test::Unit Introduction  Code Example: GoogleRank  Testing Pitfalls  Coverage Analysis  Next Steps Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  3. 3. Test-Driven Development is the process of testing the behavior of non-existent objects Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  4. 4. Testing Cycle Write Failing Test Refactor Write Code Verify Success Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  5. 5. Why Test First?  No untested code is written  Start with higher code coverage  Rapid feedback  Build your regressions as you go Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  6. 6. Anatomy of a (Test::Unit) Test Case Test case Test setup (run every test) Test Assertion Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  7. 7. Naming Conventions Method to test Parameters / Input Expected behavior (should ...) Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  8. 8. Basic Assertions  assert  assert_equal / assert_not_equal  assert_nil / assert_not_nil  assert_match / assert_no_match  assert_raise / assert_nothing_raised Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  9. 9. Code Example Class that retrieves Google results  Retrieves only the top 10 URLs  URL encodes provided search terms  Makes an HTTP connection to Google  Raises an exception when unavailable Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  10. 10. Start Small test_google_rank_should_exist(GoogleRankTest): Exception raised: Class: <NameError> Message: <"uninitialized constant GoogleRankTest::GoogleRank"> 1 tests, 0 assertions, 1 failures, 0 errors 1 tests, 0 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  11. 11. Simplest Thing That Works Class method test_parse_with_empty_document_should_return_empty_array(GoogleRankTest): NoMethodError: undefined method `parse' for GoogleRank:Class 1 tests, 0 assertions, 0 failures, 1 errors Instance method test_parse_with_empty_document_should_return_empty_array(GoogleRankTest): NoMethodError: undefined method `parse' for GoogleRank:Class 1 tests, 0 assertions, 0 failures, 1 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  12. 12. Simplest Thing That Actually Works 2 tests, 1 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  13. 13. Use a Canned Data Set Sample markup from Google search test_parse_with_sample_document_should_return_list_of_urls <["http://blog.viget.com/", ..... > expected but was <[]>. 1 tests, 1 assertions, 1 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  14. 14. Use a Canned Data Set 1 tests, 1 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  15. 15. Running Regressions test_parse_with_empty_document_should_return_empty_array(GoogleRankTest): NoMethodError: undefined method `[]' for nil:NilClass 3 tests, 1 assertions, 0 failures, 1 errors results.nil? == true Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  16. 16. Fix Regressions 3 tests, 2 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  17. 17. Code Example Class that retrieves Google results  Retrieves only the top 10 URLs  URL encodes provided search terms  Makes an HTTP connection to Google  Raises an exception when unavailable Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  18. 18. Retrieve Internal State Inspect instance variable NameError: uninitialized constant GoogleRankTest::ERB Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  19. 19. Retrieve Internal State test_new_should_encode_supplied_keywords(GoogleRankTest): ArgumentError: wrong number of arguments (1 for 0) 1 tests, 0 assertions, 0 failures, 1 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  20. 20. Retrieve Internal State 1 tests, 1 assertions, 0 failures, 0 errors 4 tests, 3 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  21. 21. Refactor Test Duplication 4 tests, 3 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  22. 22. Testing Encoding test_new_should_assign_url_with_base_and_encoded_keywords(GoogleRankTest): NameError: uninitialized constant GoogleRank::BASE_URL 1 tests, 0 assertions, 0 failures, 1 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  23. 23. Testing Encoding 1 tests, 1 assertions, 0 failures, 0 errors 5 tests, 4 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  24. 24. Code Example Class that retrieves Google results  Retrieves only the top 10 URLs  URL encodes provided search terms  Makes an HTTP connection to Google  Raises an exception when unavailable Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  25. 25. “Mock objects are simulated objects that mimic the behavior of real objects in controlled ways” - Wikipedia Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  26. 26. Mocks and Stubs  Remove external dependencies  Create known state  Focus tests on specific code paths Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  27. 27. Mocha to Stub Net::HTTP Implementation will use Net::HTTP#get test_retrieve_content_should_set_content(GoogleRankTest): NoMethodError: undefined method `retrieve_content' for #<GoogleRank:0x104053c> 1 tests, 0 assertions, 0 failures, 1 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  28. 28. Mocha to Stub Net::HTTP 6 tests, 5 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  29. 29. No Network? Oops! $ irb --prompt simple >> gr = GoogleRank.new('rails') => #<GoogleRank:0x54c89c @encoded_keywords="rails", @url="http://www.google.com/search?q=rails"> >> gr.retrieve_content SocketError: getaddrinfo: No address associated with nodename Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  30. 30. Replicate Real-Word Conditions Expected failure test_retrieve_content_when_connection_fails_should_set_content_to_nil(GoogleRankTest): SocketError: SocketError 1 tests, 0 assertions, 0 failures, 1 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  31. 31. Dealing With Failure 7 tests, 6 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  32. 32. Code Example Class that retrieves Google results  Retrieves only the top 10 URLs  URL encodes provided search terms  Makes an HTTP connection to Google  Raises an exception when unavailable Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  33. 33. Dealing With Even More Failure test_retrieve_content_when_connection_fails_should_raise_exception_and_set_content_to_nil(GoogleRankTest) <GoogleRank::ConnectionError> exception expected but none was thrown. test_retrieve_content_with_failure_should_raise_exception(GoogleRankTest) <GoogleRank::ConnectionError> exception expected but was Class: <NoMethodError> Message: <"undefined method `closed?' for nil:NilClass"> 7 tests, 6 assertions, 2 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  34. 34. Handling Unsuccessful Requests 8 tests, 8 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  35. 35. Testing Pitfalls Things to avoid  Over-mocking  Invalid mocks  Testing library code  “Assertion-heavy” tests  Non-descriptive test names Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  36. 36. Testing Pitfalls Should test parsing HTTPResponse#content does not exist Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  37. 37. Testing Pitfalls Use secondary test to verify Expected behavior? Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  38. 38. Coverage Analysis  Shows ‘tested’ code  Indication of when to stop  Can present a false impression Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  39. 39. Coverage With RCov Exception-prone Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  40. 40. Next Steps?  Rake - Rake::TestTask  Mock expectations as tests  Testing Macros Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  41. 41. Rake::TestTask Example $ rake -T rake test:all # Run tests for all Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  42. 42. Expectations as Tests attr_accessor :content called once Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  43. 43. Testing Macros Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  44. 44. Resources Test::Unit  http://ruby-doc.org/stdlib Mocha  http://mocha.rubyforge.org RCov  http://eigenclass.org/hiki/rcov Rake  http://rake.rubyforge.org How to Test Validations (Expectations as Tests)  http://relevancellc.com/2007/7/16/how-to-test-validations-part-4 Testing Macros  http://www.extendviget.com Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  45. 45. Slides http://www.slideshare.net/viget Blog http://blog.viget.com http://www.sneaq.net Contact patrick@viget.com Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  1. A particular slide catching your eye?

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

×