I'm using guard to run all my rails specs and its awesome. I've written a bunch of request specs that use capybara and selenium to test my pages javascripts by opening firefox and they are awesome as well however they tend to be slow and pull focus away from my editor while I'm typing.
Is there a way to configure guard to not run my request specs when it runs all and maybe asign a hot key to just run the request specs?
Answering my own question incase other come across this:
rspec-rails can pass command line arguments to rspec via :cli. Additionally examples can be tagged in spec files and then rspec can be run to include or exclude those tagged examples.
Turns out I'm already tagging the examples I wanted to exclude with :js=>true, wich is how you get Selenium to fire up firefox.
describe "Post" do
it "should be able to edit a post", :js=>true do
# your test here
end
end
I made two groups in my Guardfile one for none-javascript specs with :cli => "-t ~js" and another for spec that test javascript with :cli => "-t js". I also passed in the :all_after_pass => false for the javascript group.
here is my new guard file:
group 'none-javascript specs' do
guard 'rspec', :version => 2, :cli => '-r rspec/instafail -f RSpec::Instafail -t ~js' do
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/acceptance/#{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/requests/#{m[1]}_spec.rb" }
end
end
group 'javascript specs' do
guard 'rspec', :version => 2, :all_after_pass => false, :cli => '-r rspec/instafail -f RSpec::Instafail -t js' do
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
watch(%r{^spec/requests/.+_spec\.rb$})
end
end
Now when I start up guard or hit return in the guard term both groups are run executing all specs.
Guard::RSpec is running, with RSpec 2!
Running all specs
Run options: exclude {:js=>true}
...
Finished in 75.78 seconds
428 examples, 0 failures, 1 pending
Guard::RSpec is running, with RSpec 2!
Running all specs
Run options: include {:js=>true}
...
Finished in 63.68 seconds
22 examples, 0 failures
After all test pass only the none-javascript examples are run.
There's an exclude option for guard-rspec. It was implemented in #23, but wasn't documented in the README. I've made a pull request to document that.
Example
guard 'rspec', :exclude => "spec/foo/**/*" # exclude files based on glob
Related
I have just switched from using Spork with Guard to using Zeus
I used this step by step guide: http://blog.blenderbox.com/2014/04/10/testing-rails-3-with-guard-and-zeus/
The thing, is now my routine is
in a terminal window do $ zeus start
in another terminal window: guard
in another window : $rspec
My tests are working fine but I'm very surprised that rspec test suite has gotten slower than with Spork as most people say it's a huge boost in test speed.
What also makes me really think there's a bug is that when I type rspec, it displays a message reading what's below before running tests:
No DRb server is running. Running in local process instead
Somebody got an idea what's the problem ?
thanks
guardfile
require 'active_support/core_ext'
require 'active_support/inflector'
# NEw ZEUS guard
# source - blog.blenderbox.com/2014/04/10/testing-rails-3-with-guard-and-zeus/
guard 'zeus-client', :all_on_start => false, :all_after_pass => false do
ignore %r{^\.zeus\.sock$}
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)$}) { |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/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
# Capybara features specs
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
guard 'rails-assets', :run_on => [:start, :change] do
watch(%r{^app/assets/.+$})
watch('config/application.rb')
end
You may have the --drb option set in your .rspec file. Delete that line.
When spec or model changed, guard with options spring rspec shows next output:
04:54:44 - INFO - Running: spec/models/identity_spec.rb
Version: 1.1.2
Usage: spring COMMAND [ARGS]
Commands for spring itself:
binstub Generate spring based binstubs. Use --all to generate a binstub for all known commands.
help Print available commands.
status Show current status.
stop Stop all spring processes for this project.
Commands for your application:
rails Run a rails command. The following sub commands will use spring: console, runner, generate, destroy.
rake Runs the rake command
Frame number: 0/0
I'm using ruby '2.1.0' and 'rails', '4.1.0.rc1' with spring. So, it looks like it doesn't run anything. I tried different cmd options.
guard :rspec do
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/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
end
This throws en error:
05:04:08 - INFO - Running: spec/models/identity_spec.rb
05:04:08 - ERROR - Guard::RSpec failed to achieve its <run_on_modifications>, exception was:
> [#] NoMethodError: undefined method `parse_options' for #<RSpec::Core::ConfigurationOptions:0x007fad670937a8 #args=[]>
> [#] /Users/alder/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/guard-rspec-4.2.2/lib/guard/rspec/command.rb:33:in `_rspec_formatters'
> [#] /Users/alder/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/guard-rspec-4.2.2/lib/guard/rspec/command.rb:29:in `_visual_formatter'
> [#] /Users/alder/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/guard-rspec-4.2.2/lib/guard/rspec/command.rb:21:in `_parts'
> [#] /Users/alder/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/guard-rspec-4.2.2/lib/guard/rspec/command.rb:14:in `initialize'
Full content there with spec helper
I've tried all different variations of options rspec, spring rspec spec and other possible including without any, but had the same result.
rspec spec without guard works fine.
I found similar problem, but it works without spring.
try using
guard 'rspec', :cli => '--drb' do
#your code
end
once I wrote this quick guild for my reference, see if that works for you
HIH
Found the problem. In guard-rspec/guard-rspec.gemspec from 4.2.2 version, line:
s.add_dependency 'rspec', '>= 2.14', '< 4.0'
Conflicted with beta version i guess. So i changed it on next:
s.add_dependency 'rspec', '>= 2.14', '~> 3.0.0.beta2', '< 4.0'
And it works!
And by the way, option spring in cmd caused test to do nothing. So, works this:
guard :rspec, cmd: 'rspec -f doc --color --require spec_helper ' do
And just guard :rspec do, and it consider options from .rspec file, in which i wasn't sure.
I have more than three guard gems in my Guardfile. When I run guard, I want a specific guard gem is to be disabled, without removing it from Guardfile. How should I disable it?
My next question is, rspec stops running test when it finds a first error. Is there any way to run all rspec errors at a time.
What are the guard gems are essential and easy to implement?
My Guardfile
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
guard 'migrate' do
watch(%r{^db/migrate/(\d+).+\.rb})
watch('db/seeds.rb')
end
guard :annotate do
watch( 'db/schema.rb' )
# Uncomment the following line if you also want to run annotate anytime
# a model file changes
watch( 'app/models/*.rb' )
# Uncomment the following line if you are running routes annotation
# with the ":routes => true" option
watch( 'config/routes.rb' )
end
guard :bundler do
watch('Gemfile')
# Uncomment next line if your Gemfile contains the `gemspec' command.
# watch(/^.+\.gemspec/)
end
guard :rspec do
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|\.slim)$}) { |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/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
# Capybara features specs
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
# Turnip features and steps
watch(%r{^spec/acceptance/(.+)\.feature$})
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end
guard :rubocop do
watch(%r{.+\.rb$})
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
end
### Guard::Sidekiq
# available options:
# - :verbose
# - :queue (defaults to "default") can be an array
# - :concurrency (defaults to 1)
# - :timeout
# - :environment (corresponds to RAILS_ENV for the Sidekiq worker)
guard 'sidekiq', :environment => 'development' do
watch(%r{^workers/(.+)\.rb$})
end
guard 'rails' do
watch('Gemfile.lock')
watch(%r{^(config|lib)/.*})
end
# Sample guardfile block for Guard::Haml
# You can use some options to change guard-haml configuration
# output: 'public' set output directory for compiled files
# input: 'src' set input directory with haml files
# run_at_start: true compile files when guard starts
# notifications: true send notifictions to Growl/libnotify/Notifu
# haml_options: { ugly: true } pass options to the Haml engine
guard 'puma' do
watch('Gemfile.lock')
watch(%r{^config|lib|api/.*})
end
guard 'rake', :task => 'build' do
watch(%r{^my_file.rb})
end
Group your Guard plugins into groups. This allows you to select a specific group from the command line or switch them at runtime using the scope interactor command.
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?
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).
I believe the fix is to combine both groups into a single group and use && between the commands. That way, the second part of the command will only run if the first part returns true:
cmd: `zeus rspec --color --format nested --fail-fast -t ~js && zeus rspec --color --format nested --fail-fast -t js`
For more info on && see What is the purpose of "&&" in a shell command?.
I have a feature spec like spec/features/awesome_feature_spec.rb which requires spec/shared_examples/awesome_spec.rb. The latter contains all the shared_examples I am using in awesome_feature_spec.rb. When an example fails and I edit a file to fix it and save it, guard is trying to run that example again, but it directly runs awesome_feature.rbinstead of awesome_feature_spec.rb since the failed shared example is in awesome_feature.rb. This causes an error of course, since it needs to run awesome_feature_spec.rb which is the actual feature spec.
This is how my Guardfile looks like:
guard :rspec do
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|\.slim)$}) { |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/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
# Capybara features specs
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
watch(%r{^spec/shared_examples.*/(.+)\.rb$}) { |m| "spec/features/#{m[1]}_spec.rb" }
# Turnip features and steps
watch(%r{^spec/acceptance/(.+)\.feature$})
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end
Can anyone help me making guard run the feature spec and not the file which contains the shared examples?
Thank you very much in advance :)
EDIT: I didn't read the question properly. This won't solve the question above, but if anyone else happens to come across this question when googling for an answer about guard-rspec only running failing specs, hopefully this will help.
This is the 'focus mode' feature of guard-rspec. It remembers any failed specs from the last run and keeps running them until they pass.
To disable it, add failed_mode: :none to your RSpec options in Guardfile:
rspec_opts = {
failed_mode: :none,
# other options...
}
guard :rspec, rspec_opts do
# watches, etc...
end
See: https://github.com/guard/guard-rspec for more details.
It's confirmed issue in guard-rspec (https://github.com/guard/guard-rspec/issues/243). If you update guard-rspec to version 4.5.0 it should be fixed.
Sorry this is late but others may come seeking answers.
I'm not sure that this is exactly what you need but it sounds like you're after a finer-grained control over which files to execute.
Conditional Watch sounds like it could give you that finer control.
The syntax can be changed into a slightly less verbose syntax but the point is that you can pull in the parameters and pass them to a method with more complex logic, I believe that the params are an array of size 3 and of the form:
["path/to/controller", "controller_name", "controller"]
However, it's been a while since I set this up so you can take a peek at them by doing something like the following.
#add a watch to all view files in the app directory and print the params to stdout
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |params| puts params}
and then just play around with the logic you want.