Your SlideShare is downloading. ×
  • Like
Changing Your Mindset: Getting Started With Test-Driven Development
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Changing Your Mindset: Getting Started With Test-Driven Development

  • 4,726 views
Published

Patrick Reagan introduces the concept of Test-Driven development with code examples and gives some lessons learned from experience in the field.

Patrick Reagan introduces the concept of Test-Driven development with code examples and gives some lessons learned from experience in the field.

Published in Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • In order to keep the code to a minimum, I just discussed how I moved the File.read call (from slide 13) into a google_content() method. This was my implementation (I had saved the output to a file on disk):

    def google_content
    File.read(File.join(File.dirname(__FILE__), 'data/google_search.html'))
    end

    I like the refactoring in your example - here's a change that would combine the original concept with your changes (using Mocha to mock):

    def google_response
    content = File.read(File.join(File.dirname(__FILE__), 'data/google_search.html'))
    response = Net::HTTPSuccess.new('1.2', '200', 'OK')
    response.expects(:body).returns(content)
    response
    end

    I changed the name to reflect the changed behavior - the only improvement I can see would be to mimic different responses (e.g. server error, etc...) either as part of this method or other methods.

    Thanks for the feedback.<br /><br/>
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
4,726
On SlideShare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
189
Comments
1
Likes
4

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Changing Your Mindset Getting Started With Test-Driven Development Patrick Reagan Director, Application Development patrick@viget.com
  • 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. 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. Testing Cycle Write Failing Test Write Refactor Code Verify Success Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. 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. Naming Conventions Method to test Parameters / Input Expected behavior (should ...) Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. 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. Start Small test_google_rank_should_exist(GoogleRankTest): Exception raised: Class: <NameError> Message: <quot;uninitialized constant GoogleRankTest::GoogleRankquot;> 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. 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. 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. Use a Canned Data Set Sample markup from Google search test_parse_with_sample_document_should_return_list_of_urls <[quot;http://blog.viget.com/quot;, ..... > expected but was <[]>. 1 tests, 1 assertions, 1 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. 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. Fix Regressions 3 tests, 2 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. Retrieve Internal State Inspect instance variable NameError: uninitialized constant GoogleRankTest::ERB Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. 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. Refactor Test Duplication 4 tests, 3 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. 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. 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. “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. 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. 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. 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. No Network? Oops! $ irb --prompt simple >> gr = GoogleRank.new('rails') => #<GoogleRank:0x54c89c @encoded_keywords=quot;railsquot;, @url=quot;http://www.google.com/search?q=railsquot;> >> gr.retrieve_content SocketError: getaddrinfo: No address associated with nodename Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. Dealing With Failure 7 tests, 6 assertions, 0 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. 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: <quot;undefined method `closed?' for nil:NilClassquot;> 7 tests, 6 assertions, 2 failures, 0 errors Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. 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. Testing Pitfalls Should test parsing HTTPResponse#content does not exist Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 37. Testing Pitfalls Use secondary test to verify Expected behavior? Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. Coverage With RCov Exception-prone Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. 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. Expectations as Tests attr_accessor :content called once Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 43. Testing Macros Changing Your Mindset Getting Started With Test-Driven Development September 7th, 2007
  • 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. 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