Reputation: 682
I have simple, new Rails 4 app which clobbers the development database when I run rake test:units
, even though I've set the RAILS_ENV in test_helper.rb. I wouldn't have expected that. Here are the simple steps to reproduce it.
I have Ruby 2.0.0p247 and Rails 4.0.1.
rails new foo
rails generate scaffold gadget
rake db:migrate
I edit test/models/gadget_test.rb to look like this:
require 'test_helper'
class GadgetTest < ActiveSupport::TestCase
test "the env" do
assert_equal "test", Rails.env
end
end
and I have edited the first line of test/test_helper.rb from
ENV["RAILS_ENV"] ||= "test"
to be
ENV["RAILS_ENV"] = "test"
Even so, when the tests invoke rake test:units
it fails:
1) Failure:
GadgetTest#test_the_env test/models/gadget_test.rb:5]:
Expected: "test"
Actual: "development"
With older (Rails 3) apps I've set up, I could count on this defaulting to the test environment. What am I missing?
Upvotes: 5
Views: 2960
Reputation: 1558
As far as I can tell there shouldn't be any reason to have to force the Rails.env
to the test. So if you're test are running in the wrong env there is something setting the env somewhere in your code.
For me it was caused by env export I didn't realize someone had placed on the first line of an .rvmc
file for the app.
Removing that export RAILS_ENV=development
line from that file and restarting terminal fixed the issue.
Upvotes: 0
Reputation: 682
The real answer: there was a stray export RAILS_ENV="development"
in a shell script referenced by my profile. So this is a seat-to-keyboard interface failure, directly from Oct 31, 2013 in this thread: https://github.com/rails/rails/issues/7175
All you need to do is take that out and the problem goes away.
Upvotes: 1
Reputation: 656
TL;DR ensure that require 'rails/test_unit/railtie'
line is not commented out in config/application.rb
I had the same problem, was trying out Minitest as a replacement for TestUnit, and generated Rails application without it (rails new foobar --skip-test-unit
), but Minitest still uses test task from rails.
And I had the following code in the config/applicaiton.rb
:
# require 'rails/test_unit/railtie'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
As j_mcnally and Fitter Man pointed out, the problem is that Rails.env
caches its value before ENV['RAILS_ENV']
got set, in my case it is getting called inside Rails.groups
.
Trying to find in Rails sources how it sets proper test
env when calling rake task, I found that it does so in the rails/test_unit/railtie.rb
which got commented out.
So the solution was as simple as uncommenting require 'rails/test_unit/railtie'
line.
Hope that helps.
Upvotes: 6
Reputation: 682
Mystery solved, with a big tip of the hat to j_mcnally!
To force the Rails env to "test" in Rails 4 (and probably much earlier), it no longer suffices to change the first line of the test_helper.rb to
ENV["RAILS_ENV"] = "test"
This fails to reset the cached value of Rails.env, but if you invoke
Rails.env = "test"
It will reset the cached value properly. That said, there are other places where Rails.env is being invoked already, otherwise the cache wouldn't be set. One obvious one is bundler setup in application.rb, where it has Bundler.require(:default, Rails.env)
and changing that to Bundler.require(:default, ENV['RAILS_ENV'])
(to avoid setting the cache) still indicates that other places in the initialization must also be invoking Rails.env. The significance of all of that is that some of the setup is going to think it's running in development and then the tests will run in the "test" environment.
Net answer: I have a way to get what I want, but there may still be some danger spots lurking out there.
Upvotes: 6