Can I get RSpec NOT to abort rake on failing specs?

At work we’ve got a rather complex app with both specs and tests. Our
default rake task runs all our our tests and specs. We’ve also got
separate
rake tasks to run groups of tests and specs in the various
subdirectories.
The default task simply lists all the individual tasks as pre-reqs.

We do a lot of branching and merging, so we really want to run all of
the
tests and specs to see all failures.

We just realized that Rspec is aborting rake when a spec fails or errors
in
an individual rake task. I’ve been trying to fix this to no avail. I
notice that SpecTask has an attribute accessor fail_on_error which looks
like it SHOULD prevent terminating rake if it’s set to false. So I
tried
that and it doesn’t seem to work. Here’s our projects
lib/tasks/spec.rake,
any ideas?

def spec_tasks
%w{spec:controllers spec:models spec:helpers spec:views spec:lib} +
spec_subdirs.map {|t| “spec:#{t}”}
end

begin
require RAILS_ROOT + ‘/vendor/plugins/rspec/lib/spec/rake/spectask’

namespace :spec do
spec_subdirs.each do |task|
next if Rake::Task.task_defined?(“spec:#{task}”)

 desc "Run the specs under spec/#{task}"
 Spec::Rake::SpecTask.new(task) do |t|
   t.fail_on_error = false
   t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
   t.spec_files = FileList["spec/#{task}/*_spec.rb"]
 end

 namespace(task) do
   Spec::Rake::SpecTask.new(:rcov) do |t|
     t.fail_on_error = false
     t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
     t.rcov_opts = ['--include', "\"app/#{task}/.*.rb$\""]
     t.rcov = true
     t.spec_files = FileList["spec/#{task}/*_spec.rb"]
   end
 end

end
end
rescue LoadError => e
puts “Spec tasks are not available - #{e}”
end

namespace :spec do
desc “Run each set of specs individually”
task :each => spec_tasks
end


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Jul 9, 2008, at 5:52 PM, Rick DeNatale wrote:

errors in an individual rake task. I’ve been trying to fix this to

begin
require RAILS_ROOT + ‘/vendor/plugins/rspec/lib/spec/rake/spectask’

namespace :spec do
spec_subdirs.each do |task|
next if Rake::Task.task_defined?(“spec:#{task}”)

spec:models, views, controllers and helpers are all defined already in
vendor/plugins/rspec-rails/tasks/rspec.rake, so the next keyword is
being invoked for all of those. You’ll need to undefined them before
you redefine them here.

spec_tasks.each {|t| Rake::Task::TASKS.delete t}

Cheers,
David

On Wed, Jul 9, 2008 at 10:09 PM, David C. [email protected]
wrote:

On Jul 9, 2008, at 5:52 PM, Rick DeNatale wrote:

spec:models, views, controllers and helpers are all defined already in
vendor/plugins/rspec-rails/tasks/rspec.rake, so the next keyword is being
invoked for all of those. You’ll need to undefined them before you redefine
them here.

spec_tasks.each {|t| Rake::Task::TASKS.delete t}

Thanks David, I figured it was something like that. I had to modify it
a
bit since there is no TASKS constant. Rake::Task does have a tasks
method,
but it wasn’t clear that deleting an element would work since it must be
flattening the task namespace hierarchy. So I ended up with this:

begin
require RAILS_ROOT + ‘/vendor/plugins/rspec/lib/spec/rake/spectask’

namespace :spec do
spec_subdirs.each do |task|
if Rake::Task.task_defined?(“spec:#{task}”)
Rake::Task[“spec:#{task}”].fail_on_error = false
else
desc “Run the specs under spec/#{task}”
Spec::Rake::SpecTask.new(task) do |t|
t.spec_opts = [‘–options’,
“"#{RAILS_ROOT}/spec/spec.opts"”]
t.spec_files = FileList[“spec/#{task}/_spec.rb"]
t.fail_on_error = false
end
end
if Rake::Task.task_defined?(“spec:#{task}:rcov”)
Rake::Task[“spec:#{task}:rcov”].fail_on_error = false
else
namespace(task) do
Spec::Rake::SpecTask.new(:rcov) do |t|
t.spec_opts = [‘–options’,
“"#{RAILS_ROOT}/spec/spec.opts"”]
t.rcov_opts = [‘–include’, ""app/#{task}/.
.rb$"”]
t.rcov = true
t.fail_on_error = false
t.spec_files = FileList[“spec/#{task}/*_spec.rb”]
end
end
end
end
end
rescue LoadError => e
puts “Spec tasks are not available - #{e}”
end

But this still DOESN’T WORK.

It turns out that this code is running BEFORE the plugin creates its
tasks
so those are overwriting mine.

I’m beginning to think that I need to patch RSpec to allow the default
value
of fail_on_error to be set with either an environment variable or in
spec.opts.

Thoughts?

Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/