I added some long-running integration tests to a Rails application today and quickly began getting irritated that issuing the rake command runs all tests… unit, functional, AND integration. Since I run rake quite frequently, any sizable delay can quickly get annoying.

The task that gets executed by rake is the :test task. After spending a few minutes trying to replace it, I discovered that there isn’t an immediately obvious way to override an existing task in Rake. After jumping through a few hoops, though, I did manage to do it.

First, here’s my replacement for the existing :test task:

task :test do
  Rake::Task["test:units"].invoke rescue got_error = true
  Rake::Task["test:functionals"].invoke rescue got_error = true
  raise "Test failures" if got_error
end

All it does is run the unit and functional tests, but no integration tests. I stuck this in my Rakefile right after the require 'tasks/rails' line. Next up, I reopened the Rake::TaskManager module to create my own little helper method to remove a task:

Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

Lastly, I called this method from another method defined inside my Rakefile. This way, I could use syntax like remove_task :test which would fit with my other task definitions in the file. This is how everything looks put together (remember that this code should be inserted immediately after the require 'tasks/rails' line or it won’t work):

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
 
# Override existing test task to prevent integrations
# from being run unless specifically asked for
remove_task :test
task :test do
  Rake::Task["test:units"].invoke rescue got_error = true
  Rake::Task["test:functionals"].invoke rescue got_error = true
  raise "Test failures" if got_error
end

This did the trick for me, but it’s kind of long. Anyone know a better way of doing it?

  • Digg
  • del.icio.us
  • Facebook
  • Google
  • LinkedIn