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!
