Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get guard to only run slow specs if fast specs pass

I have tagged my specs that require selenium with :js => true in my spec files. What I want to achieve is that guard will always run the non :js specs first and only when these specs all pass run the specs tagged with :js.

This is my current Guardfile:

group 'non-javascript specs' do
  guard 'rspec', cmd: 'zeus rspec --color --format nested --fail-fast -t ~js', parallel: false,    bundler: false, :all_on_start => false, :all_after_pass => false, :keep_failed => false do
    notification :terminal_notifier

    watch(%r{^spec/.+_spec\.rb$})
    watch(%r{^lib/(.+)\.rb$})     { |m| "spec/lib/#{m[1]}_spec.rb" }
    watch('spec/spec_helper.rb')  { "spec" }

    # Rails example
    watch(%r{^app/(.+)\.rb$})                           { |m| "spec/#{m[1]}_spec.rb" }
    watch(%r{^app/(.*)(\.erb|\.haml|\.jbuilder)$})      { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
    watch(%r{^app/controllers/(.+)_(controller)\.rb$})  { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/features/#{m[1]}_spec.rb"] }
    watch(%r{^spec/support/(.+)\.rb$})                  { "spec" }
    watch('config/routes.rb')                           { "spec/routing" }
    watch('app/controllers/application_controller.rb')  { "spec/controllers" }

    watch(%r{^app/views/(.+)/.*\.(erb|haml)$})          { |m| "spec/features/#{m[1]}_spec.rb" }
   end
 end

group 'javascript specs' do
  guard 'rspec', cmd: 'zeus rspec --color --format nested --fail-fast -t js', parallel: false, bundler: false, :all_on_start => false, :all_after_pass => false, :keep_failed => false do
    notification :terminal_notifier
    watch(%r{^app/views/(.+)/.*\.(erb|haml)$})          { |m| "spec/requests/#{m[1]}_spec.rb" }
    watch(%r{^spec/requests/.+_spec\.rb$})
    watch(%r{^spec/features/.+_spec\.rb$})
  end
end

However, with this config it will split the execution of js and non js specs, but it will always run the js specs even if the non js specs fail.

How can I tell guard to not run the second group if the first group does not pass?

like image 370
ErwinM Avatar asked Jan 12 '14 11:01

ErwinM


1 Answers

To clean things up a bit, put this in your .rspec or .rspec-local file:

--color
--format nested
--fail-fast

Solution: use halt_on_fail to stop at first group item failing:

group 'specs', halt_on_fail: true do
  js_opts = { parallel: false, bundler: false, :all_on_start => false, :all_after_pass => false, :keep_failed => false }

  guard 'rspec', js_opts.merge(cmd: 'zeus rspec -t ~js'),  do
   # (...)
  end

  guard 'rspec', js_opts.merge(cmd: 'zeus rspec -t js'),  do
   # (...)
  end
end

This should work as expected. If not submit a bug issue in https://github.com/guard/guard.

Oh, and I think you want :all_after_pass => true in the first set - because you'd likely want all the fast tests to be green before even attempting the slow ones (unless the fast ones are independent, unlikely to be broken and too plenty to run all of them).

like image 170
Cezary Baginski Avatar answered Jan 01 '23 18:01

Cezary Baginski