RCov::VerifyTask “threshold” auto-update monitor

When developing TDD or BDD in Ruby (1.9.2) using the RCov::VerifyTask you need to fullfill a certain threshold to make a build successful.

It can be quite annoying to update the (hopefully) increased threshold of the RCov::VerifyTask in your Rakefile after each successful build. So I did some experiments and the following script is the result.

A common RCov::VerifyTask setup might look like:

Spec::Rake::SpecTask.new('rcov') do |t|
  t.spec_files  = FileList['spec/**/*.rb']
  t.rcov        = true
  t.rcov_opts   = ['--exclude', 'lib', '--exclude', 'gems']
  t.libs        << Dir["lib/**/*"]
end
 
 
RCov::VerifyTask.new(:verify_rcov) do |t|
  t.threshold   = 10.00                     # to get started
  t.index_html  = 'coverage/index.html'     # the path to html report
end


It uses another :task to capture the output of the actual RCov::VerifyTask and writes the threshold into a coverage.yml file. This threshold value is taken into comparison at the next build and updated at next build if its value has increased.

First the method to read and write the `threshold’ value from/to a coverage.yml.

 
# the `log' file in `yaml' format
#
COVERAGE_YML   = 'coverage.yml'
 
# read the last 'threshold' from the .yml file
# and return `10.0' as value if the file isn't existant
#
def read_yaml_threshold
 
    threshold = 10.0
 
    return threshold unless File.exist? COVERAGE_YML
 
    yaml  = read_yaml_file COVERAGE_YML
 
    threshold = yaml["THRESHOLD"].to_s
 
    threshold.to_f
end
 
 
# write the given `value' in `yaml' format
# back into `log' file.
#
def write_yaml_threshold value
    File.open(COVERAGE_YML, 'w') do |f|
        f.write({"THRESHOLD" => value}.to_yaml)
    end
end


Now the updated rake tasks.

 
# read the previous threshold once and
# reuse it in tasks to reduce file-access
# 
@old_threshold = read_yaml_threshold
 
 
# the SpecTask from above
#
desc "Run all rspec tests with RCOV"
Spec::Rake::SpecTask.new('rcov') do |t|
  t.spec_files  = FileList['spec/**/*.rb']
  t.rcov        = true
  t.rcov_opts   = ['--exclude', 'lib', '--exclude', 'gems']
  t.libs        << Dir["lib/**/*"]
end
 
 
# the "verify" task which is still executable 
# because the`threshold' property contains the
# current `threhold' value from `coverage.yml'
#
desc "Check code-coverage of project"
RCov::VerifyTask.new(:verify_rcov) do |t|
 
  threshold   = @old_threshold
 
  Rake::Task['rcov'].execute
 
  t.threshold   = threshold
  t.index_html  = 'coverage/index.html'
end
 
 
# the actual 'capture and update' task which retrieves the 'previous' 
# threshold and executes the `VerifyTask' and captures the 'new' threshold 
# and finally compares them. if `new' threshold has increased the 
# `coverage.yml' is updated.
#
task :run_verify do |t|
 
    old_threshold = @old_threshold
 
    log = `rake verify_rcov -f #{__FILE__}` # | tee coverage_log.txt`
 
    new_threshold = threshold_from log
 
    if new_threshold.to_f > old_threshold.to_f
 
        begin
            write_yaml_threshold new_threshold
        rescue => e
            puts "ERROR #{e.message} "
        end
 
        puts "Finished ..."
 
    else
        if new_threshold.to_f >= old_threshold.to_f
            puts "Finished with `coverage' of #{new_threshold}% ..."
        else
            puts "Failed to finish with `coverage' of #{old_threshold}% => #{new_threshold}% ..."
        end
    end
end


Although i’m quite happy with it as it works for me i would like to see if either there’s a more convenient or `nerdy’ way to implement this. I’m still learning and every input is highly appreciated. :)

If you found this useful feel free to share or comment.

Kindest ~david

This article was written in Markdown Syntax
This entry was posted in experiments, howto, ruby and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">