Rake Task to Run a Custom Group of Tests

| Comments

I have not really been getting into blogging yet, obviously. It’s been several months since the most recent post. I’m in New York at the moment, getting ready to launch a rails web project. More details about that later.

For now, I just had to post something I did recently that was handy: Using rake to run a specific group of files.

There are some great built-in tasks provided by Rake. Let’s look at the testing-related ones (run rake -T to see them all):

1
2
3
4
5
6
rake test:functionals               # Run the functional tests in test/functional
rake test:integration               # Run the integration tests in test/integration
rake test:plugins                   # Run the plugin tests in vendor/plugins/*/**/test (or specify with PLUGIN=name)
rake test:recent                    # Test recent changes
rake test:uncommitted               # Test changes since last checkin (only Subversion)
rake test:units                     # Run the unit tests in test/unit

These are all very useful. But on the site I’m currently working on, I wanted to run a set of tests that were related to a section of the web site: the web store. I wanted to be able to run a specific combination of unit, functional, and integration tests.

I looked at the source for the tasks that rails provides for rake. The testing tasks are defined in lib/tasks/testing.rake in the rails distribution. The code for the unit testing task, for example:

1
2
3
4
5
6
  desc "Run the unit tests in test/unit"
  Rake::TestTask.new(:units => "db:test:prepare") do |t|
    t.libs << "test"
    t.pattern = 'test/unit/**/*_test.rb'
    t.verbose = true
  end

The files are specified as a glob. But, I did not want to use a file pattern. I consulted the rake API docs and discovered the test_files= setter method of Rake::TestTask. Here’s what I ended up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace :test do
  tests = []
  tests << "test/integration/store_test.rb"
  # models
  %w(product product_category product_categorization product_option product_option_value 
    line_item cart order shipment).each do |file|
      tests << "test/unit/#{file}_test.rb"
  end
  # controllers
  %w(cart checkout store).each do |file|
    tests << "test/functional/#{file}_controller_test.rb"
  end
  # admin controllers
  %w(products product_option_values product_options orders).each do |file|
    tests << "test/functional/admin/#{file}_controller_test.rb"
  end
  Rake::TestTask.new(:store => "db:test:prepare") do |t|
    t.libs << "test"
    t.test_files = tests
    t.verbose = true
  end
  Rake::Task['test:store'].comment = "Run the store-related tests"
end

I saved this task in lib/tasks/store_tests.rake under my project directory. Now, I can do this:

1
2
3
4
5
6
7
8
9
$ rake test:store
(in ~/rails_project)
/opt/local/bin/ruby -Ilib:test "/opt/local/lib/ruby/gems/1.8/gems/rake-0.7.1/lib/rake/rake_test_loader.rb" "test/integration/store_test.rb" "test/unit/product_test.rb" "test/unit/product_category_test.rb" "test/unit/product_categorization_test.rb"  [... etc ...]
Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.7.1/lib/rake/rake_test_loader
Started
....................................................................
Finished in 10.799886 seconds.

68 tests, 682 assertions, 0 failures, 0 errors

All the store tests are run as a group. This is a nice way to verify that things are working in the money-making part of the site.

However, I have to remember to update the task whenever I refactor or make additions. I’m thinking about symbolic links, now. Perhaps the tests could be grouped together in a directory (like test/groups/store) by making symbolic links to them in there. And, subversion deals with symlinks well…

Comments