Rails and RSpec: `rake spec` runs all specs twice

Viewed 2498

I set up a new Rails 4 app using RSpec. But when running rake rspec, all the examples are run twice:

rake spec
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
/Users/josh/.rvm/rubies/ruby-2.0.0-p353/bin/ruby -S rspec ./spec/controllers/dashboards_controller_spec.rb ./spec/models/member_spec.rb ./spec/requests/members_spec.rb ./spec/routing/members_routing_spec.rb
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
 11/11 |============================================ 100 ============================================>| Time: 00:00:00 

Finished in 0.21233 seconds
11 examples, 0 failures

Randomized with seed 15954

/Users/josh/.rvm/rubies/ruby-2.0.0-p353/bin/ruby -S rspec ./spec/controllers/dashboards_controller_spec.rb ./spec/models/member_spec.rb ./spec/requests/members_spec.rb ./spec/routing/members_routing_spec.rb
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
 11/11 |============================================ 100 ============================================>| Time: 00:00:00 

Finished in 0.18831 seconds
11 examples, 0 failures

Randomized with seed 24248

I have found some other (old) questions about this, but couldn't find a solution for me. How should I try to debug this? Running rspec works like a charm, but I'm eager to find out what's the problem here.

Here's my spec_helper.rb: https://github.com/jmuheim/transition/blob/master/spec/spec_helper.rb

And here's the original Rails project: https://github.com/jmuheim/transition

Update

I found that the spec rake task seems to be defined twice (notice the / that separates the description of each task):

$ rake -T | grep spec
...
rake spec                               # Run all specs in spec directory (excluding plugin specs) / Run RSpec code examples
...

One of them is described with Run all specs in spec directory (excluding plugin specs), one with Run RSpec code examples.

Run RSpec code examples seems to come from rspec/core/rake_task.rb. Run all specs in spec directory (excluding plugin specs) seems to come from rspec/rails/tasks/rspec.rake.

It seems to me that only one of them should exist?!

Update 2

It seems to be a problem with rspec-rails being in both the test and development groups. I added an issue about this here: https://github.com/rspec/rspec-rails/issues/904

6 Answers

Double test runs on CI

I was getting double rspec runs because the Rails spec task was clashing with the task defined by RSpec - but only on CI. The difference for me was locally I invoke:

bundle exec rake

Which doesn't have RAILS_ENV explicity set. This is fine because the project's spec_helper.rb sets ENV["RAILS_ENV"] ||= 'test'.

But on CI, the ENV already has RAILS_ENV=test set which leads to the Rails spec task also being defined, leading to double test runs.

In summary:

bundle exec rake                  # => 1 test run
RAILS_ENV=test bundle exec rake   # => 2 test runs

The fix

Clear task(:spec) after loading Rails.application.load_tasks (if you want to define the :spec task yourself).

diff --git a/Rakefile b/Rakefile
index 0f4fb7e0..94f7236a 100644
--- a/Rakefile
+++ b/Rakefile
@@ -6,14 +6,16 @@ require File.expand_path('../config/application', __FILE__)

 Rails.application.load_tasks

+task(:default).clear
+task(:spec).clear
+
 begin
   require "rspec/core/rake_task"
   RSpec::Core::RakeTask.new(:spec)
 rescue LoadError
 end

-task(:default).clear
 task default: [
   "factory_bot:lint",
   :spec,
 ]
Related