Testing a single spec, a single test, a single testcase or a single example is a great timesaver when debugging a small problem while having a large testsuite, or a testsuite with a lot of failures…
- rake test:blog -> only the Blog Testcase
- rake spec:blog -> only the Blog Spec
- rake test:blog:create -> only the tests matching /create/ in Blog
- rake spec:blog:delete -> only the first example matching /create/ in Blog
- rake test:blog_C -> only the BlogController Test
- rake test
-> first test matching x*_test.rb (searched in order: unit,functional,integration,any folder)
It will search in unit/functional/integration (test
and models/controllers/views/helpers(spec:).
Idea
As Plugin:
script/plugin install http://small-plugins.googlecode.com/svn/trunk/single_test/
piston import http://small-plugins.googlecode.com/svn/trunk/single_test/ vendor/plugins/single_test
As Task
#lib/tasks/run_single.rake
# Run specific testcase/tests or spec/example
#
# test: search in test/ unit functional integration
# spec: search in spec/ models controllers views helpers
#
# rake test:blog
# => Runs the full BlogTest unit test
#
# rake test:blog:create
# => Runs the tests matching /create/ in the BlogTest unit test
#
# rake spec:blog:create
# => Runs the first example matching /create/ in Blog spec
#
# rake test:u
# => run the first file matching u*_test.rb
#
# rake test:blog_C or test:blog_
# => Runs all tests in the BlogControllerTest functional test
rule "" do |t|
def find_example_in_spec file, test_name
File.readlines(file).each do |line|
if line =~ /.*it(.*#{test_name}.*) do/
return $1.strip.tr('\'"','')
end
end
test_name
end
# test:file:method
if t.name =~ /(spec|test):(.*)(:([^.]+))?$/
search_order = {
‘test’=> %w(unit functional integration *),
’spec’=> %w(models controllers views helpers *),
}
#collect input
type = $1
arguments = t.name.split(”:”)[1..-1]
file_name = arguments.first.sub(/_C$/,’_controller’)
test_name = arguments[1..-1].to_s
#find the file
file = nil
search_order[type].each do |folder|
FileList["#{RAILS_ROOT}/#{type}/#{folder}/**/#{file_name}*_#{type}.rb"].each do |found|
file = found
break
end
break if file
end
if file
#when spec, convert test_name regex to actual test_name
test_name = find_example_in_spec(file,test_name) if type == ’spec’ && !test_name.empty?
#run the file
case type
when ‘test’ then sh “ruby -Ilib:test #{file} -n /#{test_name}/”
when ’spec’ then sh “script/spec -O spec/spec.opts #{file}” + \
(test_name.empty? ? “”:” -e ‘#{test_name}’”)
end
end
end
end

3 comments
Comments feed for this article
April 10, 2008 at 09:54
David Salgado
I use autotest, so I find it easier to use an editor macro that disables all tests apart from the one I’ve got the cursor in, and saves the file.
Then, when autotest picks up the changes, only that one test/spec runs.
D
April 10, 2008 at 11:10
pragmatig
Sounds good too, but i am not working with textmate and sometimes only with vi from the console so this was no option for me.
April 10, 2008 at 18:42
Mark Wilden
@David: I also use autotest. Using the editor to disable all other tests sounds great! I don’t suppose your editor is vi (like mine)? No? Oh, well.
The best I’ve been able to manage is two abbreviations: one to add ‘if nil ####’ and another for ‘end ###’. One problem is that I use RSpecl, so there are often nesting levels that have to be taken into account.
Any more information about your macro you think might be helpful would be welcome!
///ark