{"id":72,"date":"2008-05-16T16:42:42","date_gmt":"2008-05-16T22:42:42","guid":{"rendered":"http:\/\/www.pervasivecode.com\/blog\/2008\/05\/16\/making-rcov-measure-your-whole-rails-app-even-if-tests-miss-entire-source-files\/"},"modified":"2008-08-27T10:09:17","modified_gmt":"2008-08-27T16:09:17","slug":"making-rcov-measure-your-whole-rails-app-even-if-tests-miss-entire-source-files","status":"publish","type":"post","link":"http:\/\/www.pervasivecode.com\/blog\/2008\/05\/16\/making-rcov-measure-your-whole-rails-app-even-if-tests-miss-entire-source-files\/","title":{"rendered":"Making Rcov measure your whole Rails app, even if tests miss entire source files"},"content":{"rendered":"<p>I&#8217;ve seen a few Rake tasks for Rcov that work OK, but which fail in an interesting way (if you care about coverage): they give your coverage metrics an unexpected boost if you have 0% coverage in one or more source files.<\/p>\n<p>Huh? Exactly. If you have 500 source files, and your test suite only <code>require<\/code>s one of them, then you get a free ride on those 499 files that have 0% coverage. Theoretically you could get 100% coverage in your report even though 499 source files are not touched at all. D&#8217;oh!<br \/>\n<!--more--><br \/>\nThe reason for this is that rcov isn&#8217;t responsible for finding all of your source files. It just measures what portion of the files which you loaded were executed. The Rake tasks that people have written just kick off the test code, which also have no need to load all of your application&#8217;s source files. They just load whatever they need, and so that&#8217;s what rcov is aware of. But that&#8217;s not answering the question you thought you were asking, which is &#8220;how much of my application is being tested?&#8221;<\/p>\n<p>You have to explicitly say that you want to see coverage numbers for all the files your tests need, plus all of the files that your tests did not touch. Put this in your test\/test_helper.rb:<\/p>\n<pre>\r\n# require the entire app if we're running under coverage testing,\r\n# so we measure 0% covered files in the report\r\ncoverage_testing_active = defined?(Rcov)\r\nif coverage_testing_active\r\n    all_app_files = Dir.glob('{app,lib}\/**\/*.rb').grep(\r\n        \/^(?!lib\\\\\/(scheduled_tasks|template_optimizer)\\\\\/)\/)\r\n    all_app_files.unshift('app\/controllers\/application.rb')\r\n    all_app_files.each{|rb| require rb}\r\nend<\/pre>\n<p>You&#8217;ll probably want to customize that regexp to weed out any .rb files that you don&#8217;t want to load during the test suite (or which aren&#8217;t your own code).<\/p>\n<p>Because of all this <code>require<\/code>-ing, you might want to apply the snippet in my <a href=\"http:\/\/www.pervasivecode.com\/blog\/2008\/05\/16\/rails-snippet-require-app-files-only-once\/\">prior post<\/a>, which eliminates duplicate required source files if they&#8217;re under your RAILS_ROOT. Otherwise you may see evidence of repeated loading of the same source files.<\/p>\n<p>With this snippet in place, you&#8217;ll still never see 0% coverage in a file. If there are zero lines of executable code in the file, it will not be listed. But you&#8217;ll see really low figures (4% etc.) for files that are loaded but not executed. Hopefully that will help you see where you&#8217;ve completely overlooked some code in your tests that users might still be able to get to.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve seen a few Rake tasks for Rcov that work OK, but which fail in an interesting way (if you care about coverage): they give your coverage metrics an unexpected boost if you have 0% coverage in one or more source files. Huh? Exactly. If you have 500 source files, and your test suite only &hellip; <a href=\"http:\/\/www.pervasivecode.com\/blog\/2008\/05\/16\/making-rcov-measure-your-whole-rails-app-even-if-tests-miss-entire-source-files\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Making Rcov measure your whole Rails app, even if tests miss entire source files&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29,26,20,30,9],"tags":[],"class_list":["post-72","post","type-post","status-publish","format-standard","hentry","category-coverage","category-ruby","category-ruby-on-rails","category-testing","category-tools"],"_links":{"self":[{"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/posts\/72"}],"collection":[{"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/comments?post=72"}],"version-history":[{"count":0,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/posts\/72\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/media?parent=72"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/categories?post=72"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.pervasivecode.com\/blog\/wp-json\/wp\/v2\/tags?post=72"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}