Now that Alex has gotten CruiseControl.rb setup setup at work, I wanted to use it to enforce good test coverage - and I wanted the output to look good doing it. Turns out this isn't that hard, but requires a few things:
- CruiseControl.rb up and running
- RSpec and the Rails RSpec plugin
- RCov (gem install rcov)
Make sure RCov is installed on whatever machine CruiseControl is installed on (and RSpec, unless it's in your rails/vendor directory) At this point all you need is a custom cruise task (CruiseControl will run rake cruise instead of the default task if a cruise task exists). Mine looks like this:
lib/tasks/cruise.rake:
rspec_base = File.expand_path("#{RAILS_ROOT}/vendor/plugins/rspec/lib") $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base) require 'spec/rake/spectask' require 'spec/rake/verify_rcov' RCov::VerifyTask.new(:verify_rcov) { |t| t.threshold = 100.0 } desc "Task for cruise Control" task :cruise do RAILS_ENV = ENV['RAILS_ENV'] = 'test' # Without this, it will drop your production database. CruiseControl::invoke_rake_task 'db:reset' CruiseControl::invoke_rake_task 'cruise_coverage' CruiseControl::invoke_rake_task 'verify_rcov' end desc "Run specs and rcov" Spec::Rake::SpecTask.new(:cruise_coverage) do |t| t.spec_opts = ['--options', "#{RAILS_ROOT}/spec/spec_rcov.opts"] t.spec_files = FileList['spec/**/*_spec.rb'] t.rcov = true t.rcov_opts = ['--exclude', 'spec,/usr/lib/ruby', '--rails', '--text-report'] end
This will invoke RSpec telling it to use RCov with a text report. If RSpec fails (broken tests) your build will fail. If it passes it will call the verify_rcov task which will parse the RCov output and fail unless the coverage is equal to or greater the percentage you set in the RCov::VerifyTask. If you do not set both ENV['RAILS_ENV'] and RAILS_ENV to test, CruiseControl will run in production mode and drop your production database. CruiseControl is awesome like that.
Manually running the specs I like the colored progress output, but for viewing in CruiseControl the colors get mangled, and it's nice to see the specdoc format - so I made a seperate .opts file for RSpec in spec/spec_rcov.opts. If you don't care, change the spec_rcov.opts above to spec.opts and ignore this part. The spec_rcov.opts I used is:
--format
specdoc
--loadby
mtime
--reverse
And that's it! You'll get a readable output, and nobody will be able to commit testless code or broken tests without breaking the build. The one with RSpec is in rspec/rake_tasks/verify_rcov.rake - Take a look at that, as it might suite your needs!
Update: updated to use the verify_rcov that comes with RSpec 1.02+. Thanks Chad!