Testing Legacy Rails Apps

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    6 Favorites & 1 Group

    Testing Legacy Rails Apps - Presentation Transcript

    1. Testing Legacy Rails Applications Evan ‘rabble’ Henshaw-Plath Yahoo! Brickhouse anarchogeek.com - testingrails.com presentation slides - slideshare.net/rabble
    2. Do We Have Legacy Already? Yes, thousands of rails apps have been built and deployed over the last three years. Many of us included few or no tests. The test-less apps still need debugging, which should be done with tests.
    3. Testing == Health Food? “We started the tests, but haven’t been updating them” “Who has time for tests?” “Testing means writing twice as much code.”
    4. Testing == Debugging
    5. no, really, it is
    6. Starting
    7. Don’t do it all at once
    8. Get Rake Working brickhouse:~/code/legacy_testing rabble$ rake (in /Users/rabble/code/legacy_testing) /opt/local/bin/ruby -Ilib:test \"/opt/local/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake/rake_test_loader.rb\" /opt/local/bin/ruby -Ilib:test \"/opt/local/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake/rake_test_loader.rb\" #42000Unknown database 'legacy_testing_development' /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/vendor/mysql.rb:523:in `read' /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/vendor/mysql.rb:153:in `real_connect' /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/ mysql_adapter.rb:389:in `connect' /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/ mysql_adapter.rb:152:in `initialize'
    9. Create your test db mysqladmin -uroot create railsapp_test
    10. Use Migrations brickhouse:~/code/legacy_testing rabble$ rake db:migrate (in /Users/rabble/code/legacy_testing) == CreateArticles: migrating ==================== -- create_table(:articles) -> 0.2749s == CreateArticles: migrated (0.2764s) =============
    11. Try Rake Again brickhouse:~/code/legacy_testing rabble$ rake (in /Users/rabble/code/legacy_testing) /opt/local/bin/ruby -Ilib:test \"/opt/local/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake/rake_test_loader.rb\" \"test/unit/ article_test.rb\" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake/rake_test_loader Started . Finished in 0.316844 seconds. 1 tests, 1 assertions, 0 failures, 0 errors /opt/local/bin/ruby -Ilib:test \"/opt/local/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake/rake_test_loader.rb\" \"test/ functional/blog_controller_test.rb\" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake/rake_test_loader Started . Finished in 0.243161 seconds. 1 tests, 1 assertions, 0 failures, 0 errors /opt/local/bin/ruby -Ilib:test \"/opt/local/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake/rake_test_loader.rb\"
    12. Scaffolding is Broken
    13. Ok now we’re ready to get started
    14. One Step At A Time
    15. find a bug - write a test
    16. refractor a method write a test
    17. Treat Each Method As Box
    18. Test One Thing At A Time
    19. What Goes In? What Comes Out?
    20. Running Tests rake & directly
    21. Running Tests with rake rake test # Test all units and functionals rake test:functionals # Run the functional tests in test/functional rake test:integration # Run the integration tests in test/integration rake test:plugins # Run the plugin tests in vendor/plugins/**/test rake test:recent # Test recent changes rake test:uncommitted # Test changes since last checkin (svn only) rake test:units # Run the unit tests in test/unit
    22. running tests directly Test::Unit automatic runner. Usage: blog_controller_test.rb [options] [-- untouched arguments] run them all ruby article_controller_test.rb give it a test name ruby article_controller_test.rb -n test_show try regular expressions ruby article_controller_test.rb -n /show/ get help: ruby --help
    23. An Example def User.find_popular(n=20) sql = \"select u.*, count(j.user_id) as popularity from users u, talks_users j where u.id = j.user_id group by j.user_id order by popularity desc limit #{n}\" return User.find_by_sql(sql) end
    24. An Example def User.find_popular(n=20) sql = \"select u.*, count(j.user_id) as popularity from users u, talks_users j where u.id = j.user_id group by j.user_id order by popularity desc limit #{n}\" return User.find_by_sql(sql) end def test_popular assert_nothing_raised { users = User.find_popular(2) } assert_equal 2, users.size, \"find_popular should return two users\" assert users.first.popularity > users.last.popularity, \"should sort popular users\" end $ ruby ./test/unit/user_test -n test_popular brickhouse:~/code/icalico/trunk/test/unit rabble$ ruby user_test.rb -n /popular/ Loaded suite user_test Started . Finished in 0.290563 seconds.
    25. Refactor def self.find_popular(n=20) return conference.attendees.find(:all, :select => \"users.*, count(talks_users.user_id) as popularity\", :joins => \"LEFT JOIN talks_users on users.id = talks_users.user_id\", :group => \"talks_users.user_id\", :order => 'popularity', :limit => n ) end $ ruby ./test/unit/user_test -n test_popular brickhouse:~/code/icalico/trunk/test/unit rabble$ ruby user_test.rb -n /popular/ Loaded suite user_test Started F Finished in 0.290563 seconds. 1) Failure: test_popular(UserTest) [user_test.rb:10]: Exception raised: Class: <NoMethodError> Message: <\"You have a nil object when you didn't expect it!\\nThe error occured while evaluating nil.attendees\"> ---Backtrace--- /Users/rabble/code/icalico/trunk/config/../app/models/user.rb:35:in `find_popular' user_test.rb:10:in `test_popular' user_test.rb:10:in `test_popular' ---------------
    26. Refactor def self.find_popular(n=20) return self.find(:all, :select => \"users.*, count(talks_users.user_id) as popularity\", :conditions => [\"users.conference_id = ? \", conference.id], :joins => \"LEFT JOIN talks_users on users.id = talks_users.user_id\", :group => \"talks_users.user_id\", :order => 'popularity', :limit => n ) end $ ruby ./test/unit/user_test -n test_popular brickhouse:~/code/icalico/trunk/test/unit rabble$ ruby user_test.rb -n /popular/ Loaded suite user_test Started . Finished in 0.290563 seconds.
    27. build test from logs ./log/development.log Processing ArticlesController#show (for 0.0.0.0 at 2006-07-20 11:28:23) [GET] Session ID: Parameters: {\"action\"=>\"show\", \"id\"=>\"2\", \"controller\"=>\"articles\"} Article Load (0.002371) SELECT * FROM articles LIMIT 1 Rendering within layouts/articles Rendering articles/show Article Columns (0.007194) SHOW FIELDS FROM articles Completed in 0.10423 (9 reqs/sec) | Rendering: 0.08501 (81%) | DB: 0.01022 (9%) | 200 OK [http://test.host/articles/show/1]
    28. the functional test ./test/functional/article_controller_test.rb require File.dirname(__FILE__) + '/../test_helper' require 'articles_controller' # Re-raise errors caught by the controller. class ArticlesController def rescue_action(e) raise e end end class ArticlesControllerTest &lt; Test::Unit::TestCase def setup @controller = ArticlesController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end # Replace this with your real tests. def test_truth assert true end end
    29. get the params ./log/development.log Processing ArticlesController#show (for 0.0.0.0 at 2006-07-20 11:28:23) [GET] Session ID: Parameters: {\"action\"=>\"show\", \"id\"=>\"2\", \"controller\"=>\"articles\"} Article Load (0.002371) SELECT * FROM articles LIMIT 1 Rendering within layouts/articles Rendering articles/show Article Columns (0.007194) SHOW FIELDS FROM articles Completed in 0.10423 (9 reqs/sec) | Rendering: 0.08501 (81%) | DB: 0.01022 (9%) | 200 OK [http://test.host/articles/show/1]
    30. what to test? 1. Assert that the page action rendered and returned successful HTTP response code, i.e. 200. 2. Assert that the correct template was rendered. 3. Assert that action assigns a value to the @article variable. 4. Assert that the right @article object was loaded.
    31. writing the test ./test/functional/article_controller_test.rb def test_show get :show, {\"action\"=>\"show\", \"id\"=>\"2\", \"controller\"=>\"articles\"} #confirm that the http response was a 200 (i.e. success) assert_response :success #confirm that the correct template was used for this action assert_template 'articles/show' #confirm that the variable @article was assigned a value assert assigns( :article ) #confirm that the @article object loaded has the id we want assert_equal 2, assigns( :article ).id end
    32. running the test rabble:~/code/tblog/test/functional evan$ ruby \\ articles_controller_test.rb -n test_show Loaded suite articles_controller_test Started F Finished in 0.625045 seconds. 1) Failure: test_show(ArticlesControllerTest) [articles_controller_test.rb:27]: <2> expected but was <1>. 1 tests, 4 assertions, 1 failures, 0 errors
    33. fix the bug The old code app/controller/articles_controller.rb: def show @article = Article.find(:first) end The fix is easy, we update it so the Article.find method app/controller/articles_controller.rb: def show @article = Article.find(params[:id]) end
    34. running the test rabble:~/code/tblog/test/functional evan$ ruby \\ articles_controller_test.rb -n test_show Loaded suite articles_controller_test Started . Finished in 0.426828 seconds. 1 tests, 3 assertions, 0 failures, 0 errors
    35. test coverage
    36. rake stats brickhouse:~/code/icalico/trunk rabble$ rake stats (in /Users/rabble/code/icalico/trunk) +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Helpers | 107 | 81 | 0| 9| 0| 7| | Controllers | 517 | 390 | 10 | 52 | 5| 5| | Components | 0| 0| 0| 0| 0| 0| | Functional tests | 416 | 299 | 18 | 58 | 3| 3| | Models | 344 | 250 | 8| 37 | 4| 4| | Unit tests | 217 | 159 | 9| 25 | 2| 4| | Libraries | 257 | 162 | 4| 32 | 8| 3| | Integration tests | 0| 0| 0| 0| 0| 0| +----------------------+-------+-------+---------+---------+-----+-------+ | Total | 1858 | 1341 | 49 | 213 | 4| 4| +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 883 Test LOC: 458 Code to Test Ratio: 1:0.5
    37. rcov test coverage
    38. rcov test coverage what needs to be tested?
    39. rcov test coverage what gets executed when you run tests
    40. rcov test coverage summary
    41. rcov test coverage per file reports
    42. Heckle more later on this
    43. autotest because sometimes our tests can run themselves
    44. autotest
    45. Continuous Integration
    46. You can go deeper
    47. Fixtures Ugliness ar_fixtures use mocks fixture senarios
    48. zentest
    49. focus on the bugs
    50. Flickr Photos •http://flickr.com/photos/maguisso/247357791/ •http://flickr.com/photos/jurvetson/482054617/ •http://flickr.com/photos/candiedwomanire/352027/ •http://flickr.com/photos/mr_fabulous/481255392/ •http://flickr.com/photos/dharmasphere/125138024/ •http://flickr.com/photos/misshaley/450106803/ •http://flickr.com/photos/19684903@N00/317182464/ •http://flickr.com/photos/planeta/349424552/ •http://flickr.com/photos/izarbeltza/411729344/ •http://flickr.com/photos/mikedefiant/447379072/ •http://flickr.com/photos/fofurasfelinas/74553343/ •http://flickr.com/photos/thomashawk/422057690/ •http://flickr.com/photos/cesarcabrera/396501977/ •http://flickr.com/photos/thearchigeek/418967228/ •http://flickr.com/photos/thomashawk/476897084/ •http://flickr.com/photos/gini/123489837/ •http://flickr.com/photos/neilw/233087821/ •http://flickr.com/photos/good_day/450356635/ •http://flickr.com/photos/ronwired/424730482/ •http://flickr.com/photos/monster/148765721/ •http://flickr.com/photos/monkeyc/200815386/ •http://flickr.com/photos/charlesfred/243202440 •http://flickr.com/photos/dramaqueennorma/191063346/ •http://flickr.com/photos/incognita_mod/433543605/ •http://flickr.com/photos/filicudi/272592045/ •http://flickr.com/photos/martinlabar/163107859/ •http://flickr.com/photos/gaspi/6281982/ •http://flickr.com/photos/iboy_daniel/98784857/ •http://flickr.com/photos/silvia31163/199478324/ •http://flickr.com/photos/tjt195/68790873/ •http://flickr.com/photos/nidriel/103210579/ •http://flickr.com/photos/charlietakesphotos/25951293/ •http://flickr.com/photos/leia/29147578/ •http://flickr.com/photos/90361640@N00/282104656/
    51. Get Your Feet Wet Next: Evan ‘rabble’ Henshaw-Plath Yahoo! Brickhouse anarchogeek.com Heckle testingrails.com slides: slideshare.net/rabble

    + Rabble .Rabble ., 3 years ago

    custom

    5774 views, 6 favs, 3 embeds more stats

    Presentation at Rails Conf 2007 about adding tests more

    More info about this document

    CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

    Go to text version

    • Total Views 5774
      • 5767 on SlideShare
      • 7 from embeds
    • Comments 0
    • Favorites 6
    • Downloads 373
    Most viewed embeds
    • 4 views on http://blog.nivta.com
    • 2 views on http://railsandruby.blogspot.com
    • 1 views on https://s3.amazonaws.com

    more

    All embeds
    • 4 views on http://blog.nivta.com
    • 2 views on http://railsandruby.blogspot.com
    • 1 views on https://s3.amazonaws.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories

    Groups / Events