imedo Development Blog

there is no charge for awesomeness

Archive for the ‘rake’ tag

Rake task for code coverage of unit and functional tests

without comments

When we tried to generate code coverage reports from our unit and functional tests on our CI system with rcov, we always had the problem of successful builds even if test errors or failures occured. This was because of rake ignoring the result code when using the system or puts command to invoke rcov.

The solution is the sh command of rake which allows us to get the result code, store it, and evaluate it after unit and functional tests have been run.

Here is the code of our rake task. It runs the unit and functional tests and generates the code coverage for both. The task was tested with rcov 0.8.1.2.0.


desc "Run unit and functional tests and measure code coverage"
task :coverage  => "db:test:prepare" do
  RAILS_ENV="test"
  result = 0
  output_dir = "test/coverage"
  rm_f "#{output_dir}/*"
  rm_f "#{output_dir}/coverage.data"
  mkdir_p output_dir
  rcov = "rcov -o #{output_dir} --rails --aggregate #{output_dir}/coverage.data --text-summary --exclude=\"gems/*,rubygems/*,rcov*\" -Ilib" 

  test_files = Dir.glob('test/unit/**/*_test.rb')
  if ! test_files.empty?
    sh %{#{rcov} --no-html #{test_files.join(' ')}} do |ok, res|
      result = result + res.exitstatus if res
    end
  end
  test_files = Dir.glob('test/functional/**/*_test.rb')
  if ! test_files.empty?
    sh %{#{rcov} --html #{test_files.join(' ')}} do |ok, res|
      result = result + res.exitstatus if res
    end
  end
  raise "Tests failed." unless result == 0
end

Popularity: 1% [?]

Written by ehartung

July 9th, 2009 at 8:13 am

Overriding rake tasks and db:test:prepare strangeness

without comments

Some time ago our CC.rb build started to fail with errors like this:

Mysql::Error: Can't create table './cc_test/#sql-8e7_5bab.frm' (errno: 150): ALTER TABLE questions ADD CONSTRAINT questions_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE

We’re using the foreign key migrations plugin which automatically generates foreign keys for mysq. It works fine but somehow the db:test:prepare rake task started to fail – everytime at a different key and only on the build server.

After hours of hunting down the problem I finally gave up and did what you always can do if you can’t solve a problem: cheat. So I just created a new db:test:prepare task which calls the mysql commands and basically does the same as the rake task. It’s not as portable as the default one, of course, but it has one property that the default one had lost: It works.

Rake doesn’t allow redefining task by default. So to override a rake task you have to delete the task and then define the new one. I opted for the manual remove task and redefine option.

Here’s my task in case anyone experiences similar problems:

We call rake using “rake -I /path/to/override.rb” in our build scripts and it works fine now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

def remove_task(task_name)
  Rake.application.remove_task(task_name)
end

namespace :db do
  namespace :test do
    remove_task :"db:test:prepare"
    desc 'prepares the db - mysql style'
    task :prepare do
    
      require 'yaml'

      config = YAML::load(File.read('config/database.yml'))

      devdb = config['development']['database']
      devpass = config['development']['password']
      devuser = config['development']['username']
      testdb = config['test']['database']
      testpass = config['test']['password']
      testuser = config['test']['username']

      puts "dumping development schema"
      puts %x{mysqldump -u #{devuser} --password=#{devpass} -d #{devdb} > dev.sql}
      puts "dropping test db"
      puts %x{mysqladmin -u #{testuser} --password=#{testpass} -f drop #{testdb}}
      puts "recreating testdb"
      puts %x{mysqladmin -u #{testuser} --password=#{testpass} create #{testdb}}
      puts "loading development schema into test db"
      puts %x{mysql -u #{testuser} --password=#{testpass} #{testdb} < dev.sql}

    end
  end
end

Popularity: 1% [?]

Written by hvolkmer

August 18th, 2008 at 12:58 pm

Posted in Deployment

Tagged with , , ,