I'm trying to test some environment-specific settings (middleware to be specific, but it doesn't seem to matter), but I'm having trouble getting the tests to run in the correct environment. The symptoms:

If I run ruby test/unit/my_test.rb, all is fine because the first thing it does is require test/test_helper.rb, which sets the environment to "test" and then loads the Rails environment.

If I run rake test, the first batch (functionals) run fine, but the second batch (units) fail. The failure is that ENV['RAILS_ENV] somehow gets unset between batches, then config/environment.rb sees that none is set and uses the default of "development". The environment is correct at the beginning of config/environment.rb and at the beginning of the configuration block in that file, but wrong by the end. I can tell by using a puts or by deleting config/development.rb causing it to not find the file.

If I run rake test:units, I get the same problem as the second batch of rake test (that is, all fail)

If I run rake test:functionals, I get the same as for rake test:units

If I run rake test RAILS_ENV=test or rake test:units RAILS_ENV=test or rake test:functionals RAILS_ENV=test, all is fine!

I even tried creating a separate one of those :set_test_env tasks for each test task so that I was sure it would get called before each one instead of just once. Still no dice. It does get called, and the environment is correct at the beginning of config/environment.rb but something goes wrong inside.

Based on your comments about environment.rb and deleting development.rb, it might help to see your environment.rb file and the stack trace or error message related to the development.rb file missing.
–
mlibbyJun 15 '09 at 21:24

It's pretty easy to do for yourself. (1) start a new Rails app. (2) in config/environtments/development.rb, add the line "raise 'development!'" at the end. (3) run "rake tests" (or just "rake") from the command line.
–
James A. RosenJun 16 '09 at 4:00

Ah. I thought maybe you had a special case, but the problem can be reproduced in a blank app. Fun puzzle. :) So far the best I can tell is that the Rails system is loaded up during test prep in order to check for pending DB migrations and that this is setting RAILS_ENV set to 'development' if ENV['RAILS_ENV'] is not already set.
–
mlibbyJun 17 '09 at 16:45

It can't quite be that simple. If it were, then that example code at the end of my post (task :set_test_env { ENV['RAILS_ENV'] = 'test' }; Rake::Task[:test].prerequisites.unshift :set_test_env) would solve the problem, which it doesn't. But we're on the right track.
–
James A. RosenJun 17 '09 at 20:29

1

The issue is that you have stuff in development.rb that clobbers your tests. Find somewhere more appropriate to put that stuff, and your problem is solved. Where to move it depends on what, exactly, it's doing, so my advice is to post your development.rb.
–
Sarah MeiSep 9 '09 at 19:01

I pretty much always want to force my tests to run themselves and their prerequisites in the "test" environment, especially when ENV['RAILS_ENV'] is set to any of the common defaults (to avoid catastrophic accidents), but I also want to be able to run tests on, say, an environment named "v_2_0_maint_test" or something like that by calling rake test:units RAILS_ENV=v_2_0_maint_test on the command line.

So I have a test_tasks.rake file that prepends a prerequisite onto each of the test tasks that I'm interested in. Since this prerequisite is prepended, any other prerequisites (e.g. db:test:prepare, db:fixtures:load) run in the same environment. This claims the virtue of affecting only the tests you want to affect, and their prerequisites.

Search through your entire project for RAILS_ENV and its variants. See if you set it somewhere in your application or in your tests.

Also, what platform are you running on? Can you run tests on another machine and see if the results are the same?

If this is a relatively recent development and you're using a RCS like Git or SVN, you should look through the recent commits, and if you're specifically using Git, you should look into git bisect. If you're not using an RCS, you should be.

If this is truly a fresh app problem, then it's probably a problem with your environment.

What plugins and gems do you have installed/configured? Can we see the backtrace?

As I said in a comment above: It's pretty easy to do for yourself. (1) start a new Rails app. (2) in config/environtments/development.rb, add the line "raise 'development!'" at the end. (3) run "rake tests" (or just "rake") from the command line. So it's not a problem with my code. And I just tried it again with a fresh installation of the Rails 2.3.3 gem.
–
James A. RosenJul 30 '09 at 18:01

2

Gaius, unfortunately your "Simple test" is not proving the point. When rake starts it will do a number of things before it loads the test helper. These tasks will be done within the currently active environment. Which by default will be development, some of these predicate tasks will load the default environment. Your simple case will not demonstrate the point if you set RAILS_ENV in the shell using export RAILS_ENV=test before running rake
–
Steve WeetJul 30 '09 at 22:04

I do not actually believe that you have an issue here at all. I believe that at some time you spotted that your rake task was actually hitting the development environment and you started to try and work out why that was the case. You then added a line within the development config file to raise an exception and this is why your rake tests are failing.

If you remove the line that is raising an exception then you may find that the tests all run succesfuly.

As I say in the first sentence of my question, the problem is that in my actual app I have lots of initialization in my development.rb that clobbers all over my tests. Removing my debugging "raise" line causes all sorts of havoc because I'm trying to interact with live (development) systems rather than fake versions.
–
James A. RosenJul 31 '09 at 11:29

But with the raise line in it is always going to fail as rake is invoked in the "Current environment". So as soon as it loads the current environment (development) it will raise the exception.
–
Steve WeetAug 18 '09 at 8:21

Gaius, the issue is that you have stuff in development.rb that clobbers your tests. Find somewhere more appropriate to put that stuff, and your problem is solved. Where to move it depends on what, exactly, it's doing.
–
Sarah MeiSep 9 '09 at 19:00

@Sarah Mei: it baffles me why I should have to worry about what's in my development.rb when I'm running tests. Tests should run exclusively in the test environment.
–
James A. RosenJan 13 '10 at 22:33