Making it easy to run a single test
In the course of normal development I find myself focusing on specific tests that I want to make sure work properly before moving on to testing the entire test suite.
There is a really great argument to test/unit
called --name
which will allow you to specify the test to run.
The test/unit
rake
tasks provide the TESTOPTS
environment variable as a means to pass options to the tests runner. To run a specific test we can add our --name
option to TESTOPTS
like this:
$ rake test:units TEST=test/unit/user_test.rb TESTOPTS="--name=test_should_create_user"
The --name
option even takes a regular expression, so we can even do this:
$ rake test:units TEST=test/unit/user_test.rb TESTOPTS="--name='/create_user/'"
Because it’s a pain in the ass to remember the option as well as doing the right amount of escaping and quoting, I created a simple rake task that you can have run before your real test tasks to set TESTOPTS
for you. It looks in the TESTNAME
environment variable and if it exists, sets TESTOPTS
with the correct value.
To pull this off, you can just put the following in lib/tasks/test_name.rake
:
namespace :test do
task :populate_testopts do
if ENV['TESTNAME'].present?
ENV['TESTOPTS'] = ENV['TESTOPTS'] ? "#{ENV['TESTOPTS']} " : ''
ENV['TESTOPTS'] += "--name=#{ENV['TESTNAME'].inspect}"
end
end
end
%w(test:units test:functionals test:integration).each do |task_name|
Rake::Task[task_name].prerequisites << 'test:populate_testopts'
end
You can find the gist here.
The only thing tricky about this code is that we go and stick an entry in the prerequisites
array that each Rake::Task
has to make sure that it runs our environment filter code before it runs the task itself.
Once we’ve done that, we can run the tests we want with:
$ rake test:units TEST=test/unit/user_test.rb TESTNAME='/create_user/'