Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate Rake test tasks dynamically (based on existing test files) in a Rakefile

I'm generating test tasks dynamically based on existing test files in a Rakefile. Consider you have various unit test files named after the pattern test_<name>.rb. So what I'm doing is creating a task named after the file name inside the 'test' namespace. With the code below I can then call all the tests with rake test:<name>

require 'rake/testtask'

task :default => 'test:all'

namespace :test do

  desc "Run all tests"
  Rake::TestTask.new(:all) do |t|
    t.test_files = FileList['test_*.rb']
  end

  FileList['test_*.rb'].each do |task|
    name = task.gsub(/test_|\.rb\z/, '')
    desc "Run #{name} tests"
    Rake::TestTask.new(:"#{name}") do |t|
      t.pattern = task
    end
  end

end

The above code works, it just seems too much code for simple task generation. And I still haven't figured out a way to print some description text to the console like puts "Running #{name} tests:"

Is there a more elegant way than the above method?

EDIT: What I really expected to get was an alternative to the loop to define the tasks dynamically but I guess the rake lib doesn't provide any helper to that so I'm stuck with the loop.

like image 440
jasoares Avatar asked Mar 02 '12 19:03

jasoares


People also ask

How do I create a run Rake task?

Go to Websites & Domains and click Ruby. After gems installation you can try to run a Rake task by clicking Run rake task. In the opened dialog, you can provide some parameters and click OK – this will be equivalent to running the rake utility with the specified parameters in the command line.

How do I create a Rake file?

Simply create a new file and name it as task. rake. Normally we put the rake task in directory lib/tasks. But you can put it anywhere you like.

What is a Rake task?

Rake is a software task management and build automation tool created by Jim Weirich. It allows the user to specify tasks and describe dependencies as well as to group tasks in a namespace. It is similar in to SCons and Make.

How do I run a Rake file?

How to run rake? To run a rake task, just call the rake command with the name of your task. Don't forget to include your namespaces when you have them.


1 Answers

Here's another way to solve the problem using rules in Rake.

A rake rule kicks in whenever rake wants to build "X", and it finds a rules that says "to build X, use Y". We will setup a rule that triggers when someone specifies a target in the format "test:XXX", it will attempt to use a file named "test/test_XXX.rb".

require 'rake/testtask'

task :default => 'test:all'

TEST_FILES = FileList['test/test_*.rb']

namespace :test do
  desc "Run all tests"
  Rake::TestTask.new(:all) do |t|
    t.test_files = TEST_FILES
  end

  rule /^test:/ => lambda { |tn| "test/test_%s.rb" % tn.gsub(/^test:/,'') } do |rule|
    ruby rule.source
  end
end

Suppose you have a test file named "test/test_my_code.rb". To execute that test file, just type:

rake test:my_code

The rule is triggered whenever there is a target beginning with "test:" that cannot matched by any other task. It then looks for a file given by the lamdba function. The lambda transforms the target name "test:XXX" into a filename "test/test_XXX.rb". If the filename exists, the body of the rule is executed.

The body of the rule just runs the test file as an executable. This is generally enough to run the tests of a single file. If you need to add library paths (e.g. "lib") to the load path for the tests, you can change the rule body to be something like

ruby "-Ilib", rule.source

Another difference between this and the explicit loop solution is that rake will not print out descriptions for rules, so the "rake -T" output won't include the individual tests in its output.

I don't know if this is better than the the original, but it does give you some options.

like image 77
Jim Weirich Avatar answered Oct 11 '22 23:10

Jim Weirich