Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for rspec rake tasks initializing in development #241

Merged
merged 5 commits into from
Jan 25, 2017
Merged

Conversation

bkeepers
Copy link
Owner

This fixes #219, which causes Rails apps to always be initialized in development when being loaded from rake, by adding a hack that sets RAILS_ENV=test when rake spec is being run.

Rails already includes a hack like this, which will set RAILS_ENV=test when running rake test. This hack used to be loaded when requiring rails/all, but rails/rails#10256 moved to to only be loaded when requiring test_unit/railtie. So, deally, rspec would copy this behavior when loading the rspec railtie.

I need to figure out a way to test this. I would appreciate any ideas for how to do that easily. The only thing I can think is to add a couple bare-bones Rails apps to the test suite that have different dependencies configured. 😞

/cc @bitherder

@bitherder
Copy link

This won't immediately work for us in two cases: 1) we often run just rake with the default task requiring spec; and 2) we (for no good reason) have specs run from tasks named things like test:backend. Of course, we can change 2) to use spec:backend, but 1) will continue to be a problem.

@skaes
Copy link

skaes commented Jul 1, 2016

@bitherder actually, rails already takes care of 'default' and 'test' tasks

@bitherder
Copy link

@bkeepers, what do you think about merging this?

* origin/master:
  Fix deprecation warning
  Release 2.1.1
  Fix a failure spec in ruby 2.4.0dev
  Fix load error when using Spring w/ custom config
  Allow failures for jruby-head until next release
  Run rubucop with default rake task
  Lock to version of rubocop
  Test against Ruby 2.3.0 on Travis CI
bitherder added a commit to bitherder/rspec-rails that referenced this pull request Jul 4, 2016
This hack mirrors a hack in Rails for test::unit.
(See https://github.com/rails/rails/blob/99873ca1ea98d73c73f8be60dfce0a54224f4ea8/railties/lib/rails/test_unit/railtie.rb)

In my particular situation (general issue for XING), this change
prevents a problem with the use of the dotenv gem where environment
variable values for development leak into the test environment.
(See bkeepers/dotenv#219 and bkeepers/dotenv#241)
@bitherder
Copy link

See rejection of pull request to rspec-rails: rspec/rspec-rails#1651

* origin/master:
  Switch to FAQ format at bottom
  add note that it won't overwrite existing env variables
  Allow following whitespace
  Prepare for 2.1.2
  Prepare for 2.1.2
  Allow leading whitespace
  Docs for loading multiple files
  Add dotenv/load to README
  Reorganize docs, document variable substitution
  Remove whitespace
  Nokogiri 1.7 requires Ruby version >= 2.1.0
  Travis 'Ruby rbx-2' failing on master
  Use the latest rubies on Travis
  Rack 2 requires Ruby version >= 2.2.2
  CI against Ruby 2.4.0
  Loosen the railties version
  Reorder to make the load method available
  fix typo (charriage returns) in changelog
  add helper file that loads when required
* master:
  Drop support for 1.9
  Fix a build error on Travis CI by using latest RubyGems
@bkeepers bkeepers merged commit f1f4324 into master Jan 25, 2017
@bkeepers bkeepers deleted the rake-rspec branch January 25, 2017 14:28
dsander added a commit to dsander/dotenv that referenced this pull request Jan 3, 2020
This is a followup of bkeepers#241 and brings the `dotenv-rails` environment
assigning hack in line with the [logic rails uses when the
`test_unit/railtie` is loaded][1].

This is a breaking change for all non `test-unit` users, but brings the
behavior of `dotenv-rails` in line across all uses of `rake test`, `rake
rspec`, `rspec` and `rake`.

Before this change `dotenv-rails` loaded different env files when using
a rails application with `rspec` for tests. `rake spec` was covered by
the previous logic and set the RAILS_ENV to test. Only running `rake`
(which invokes rspec by default) wasn't covered and thus loaded first
the development env files and later the test env.

[1]: https://github.com/rails/rails/blob/6-0-stable/railties/lib/rails/test_unit/railtie.rb#L5-L7
lawrence-forooghian added a commit to DFE-Digital/claim-additional-payments-for-teaching that referenced this pull request Jan 23, 2020
We use the default Rake task as our standard invocation for running the
test suite and other code quality checks. We noticed that running
`bundle exec rake` was causing dotenv to use the ENVIRONMENT_NAME
variable from the .env.development file, and not .env.test as expected.
A recent change in 1d57789 to the values of ENVIRONMENT_NAME in
.env.development hence caused the tests to start failing when run
locally.

We found out that other people have also been experiencing this issue
[1]. The linked comment explains in detail what causes this to happen:

> Actually, I found that it will load `.env.test`, but because `.env.development` was already loaded before `.env.test`, and since `Dotenv.load` won't override the env var if it exist, it will use var defined in `.env.development` not `.env.test`.
>
> The whole process is like this:
>
> 1. `rake spec` call Rakefile in root folder, which will
>    `require File.expand_path('../config/application', __FILE__)`
> 2. application will trigger [`before_configuration` hook defined by dotenv](https://github.com/bkeepers/dotenv/blob/master/lib/dotenv/rails.rb#L20), which will load following 3 env files:
>
>    * `.env.local`
>    * `.env.development`
>    * `.env`
> 3. spec rake task get call, and call this code in your spec:
>    ```
>    require 'rails_helper'
>    ```
> 4. In rails_helper.rb, ENV['RAILS_ENV'] was set to 'test'.
> 5. Then, config/application.rb was required again by `config/environment`, and `before_configuration` hook was triggered, only now `Rails.env == 'test'`. Therefore, it will load following 3 files:
>
>    * `.env.local`
>    * `.env.test`
>    * `.env`
>
> But since `before_configuration` hook is using `load`, it won't override existing value.

The gist is that dotenv ends up loading the .env.development file
first, and then loads the .env.test file. However, by default dotenv
will not overwrite the variables defined in the first file with those
defined in the second, so we end up with the incorrect ENVIRONMENT_NAME
being used.

The same comment suggested adding `Dotenv.overload('.env.test')` to
`spec/rails_helper.rb`. This wasn't sufficient for us, since by the time
this happens, our config/initializers/dfe_sign_in.rb had already grabbed
the (wrong) values from the environment.

Anyway, ideally, we don't want to load the .env.development file _at
all_ when running the tests, so I didn't try to figure out how to make
the previous approach work. Instead, we noticed that dotenv contains a
special hack, which sets RAILS_ENV to `test` when the currently-running
Rake task is `spec` [2]. There is currently an open pull request on
dotenv which does the same thing when running the default Rake task [3],
but it doesn't seem to have attracted any attention.

In the end I decided to emulate the dotenv hack, by setting RAILS_ENV to
`test` if running the default Rake task. I do this in the Rakefile,
before any of the Rails application is loaded, to ensure that setting
this environment variable happens before dotenv has a chance to load
.development.env.

[1] bkeepers/dotenv#219 (comment)
[2] bkeepers/dotenv#241
[3] bkeepers/dotenv#405
stevenday pushed a commit to openownership/register that referenced this pull request Mar 19, 2020
When rspec is run via rake, the RAILS_ENV isn't set soon enough
for dotenv-rails to know that we're in the test environment and
load the appropriate .env file. They added a fix in:
bkeepers/dotenv#241 which solves the issue
by looking at the arguments to Rake, hence the upgrade from our
older version.
stevenday pushed a commit to openownership/register that referenced this pull request Mar 20, 2020
When rspec is run via rake, the RAILS_ENV isn't set soon enough
for dotenv-rails to know that we're in the test environment and
load the appropriate .env file. They added a fix in:
bkeepers/dotenv#241 which solves the issue
by looking at the arguments to Rake, hence the upgrade from our
older version.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rake tasks in Rails always initialized in "development"
3 participants