Skip to content

Commit

Permalink
Do load .env.local in Rails' test environment
Browse files Browse the repository at this point in the history
This basically reverts bkeepers#280.

The above-mentioned PR says:

> When using .env.local for tests, the tests are not transparent and
> can't be executed for example on a CI server.
> As the documentation says, the .env.local is here for local
> overwrites. They should not overwrite a test specific variable. Tests
> should be run on every machine in every environment and shouldn't
> require any specification of environment variables.

While that description matches the expected behavior of Dotenv, the
implementation goes too far (1) and even contradicts other bits of Dotenv's
current behavior (2).

About (1), a [quote][jakedouglas-comment] from the Github user named jakedouglas:

>> Tests should be run on every machine in every environment and
>> shouldn't require any specification of environment variables.
>
> At least one very common example of this idea not holding water is
> that most Rails applications require a database, and the URL of that
> database may vary between different developer machines, and between
> developer machines and a CI service. Given this PR, if a developer
> happens to have a database setup that doesn't match the
> application's defaults (common), they need to specify the database
> URL in both .env.local and .env.test.local in order to do local
> development comprehensively.

About (2), anything that .env.local could do to the test environment
variables before it became ignored for that environment can now be done
with .env.test.local, often at the cost of tediously duplicating
variables from the currently-ignored .env.local. This contradicts the
behavior intended by PR bkeepers#280 and consistency would dictate that
.env.test.local be removed altogether. Only then the test variables
would truly be guaranteed to always stay the same as far as Dotenv is
concerned.

Since (1) shows that local development might require local test
variables for legitimate reasons, removing .env.test.local is not a
valid option and it would make sense to instead restore loading
.env.local for the test environment.

[jakedouglas-comment]: bkeepers#280 (comment)
  • Loading branch information
Erwan Thomas committed Oct 26, 2020
1 parent 9e101a5 commit ec2c601
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ If you use this gem to handle env vars for multiple Rails environments (developm
| 1st (highest) | `.env.development.local` | Development | Yes! | Local overrides of environment-specific settings. |
| 1st | `.env.test.local` | Test | Yes! | Local overrides of environment-specific settings. |
| 1st | `.env.production.local` | Production | Yes! | Local overrides of environment-specific settings. |
| 2nd | `.env.local` | Wherever the file is | Definitely. | Local overrides. This file is loaded for all environments _except_ `test`. |
| 2nd | `.env.local` | Wherever the file is | Definitely. | Local overrides. This file is loaded for all environments. |
| 3rd | `.env.development` | Development | No. | Shared environment-specific settings |
| 3rd | `.env.test` | Test | No. | Shared environment-specific settings |
| 3rd | `.env.production` | Production | No. | Shared environment-specific settings |
Expand Down
2 changes: 1 addition & 1 deletion lib/dotenv/rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def self.load
def dotenv_files
[
root.join(".env.#{Rails.env}.local"),
(root.join(".env.local") unless Rails.env.test?),
root.join(".env.local"),
root.join(".env.#{Rails.env}"),
root.join(".env")
].compact
Expand Down
16 changes: 9 additions & 7 deletions spec/dotenv/rails_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,18 @@ def add(*items)
expect(Spring.watcher.items).to include(path)
end

it "does not load .env.local in test rails environment" do
it "loads .env.local in test rails environment" do
expect(Dotenv::Railtie.instance.send(:dotenv_files)).to eql(
[
Rails.root.join(".env.test.local"),
Rails.root.join(".env.local"),
Rails.root.join(".env.test"),
Rails.root.join(".env")
]
)
end

it "does load .env.local in development environment" do
it "loads .env.local in development environment" do
Rails.env = "development"
expect(Dotenv::Railtie.instance.send(:dotenv_files)).to eql(
[
Expand All @@ -72,8 +73,8 @@ def add(*items)
)
end

it "loads .env.test before .env" do
expect(ENV["DOTENV"]).to eql("test")
it "loads .env.local before .env" do
expect(ENV["DOTENV"]).to eql("local")
end

context "when Rails.root is nil" do
Expand All @@ -91,17 +92,18 @@ def add(*items)
context "overload" do
before { Dotenv::Railtie.overload }

it "does not load .env.local in test rails environment" do
it "loads .env.local in test rails environment" do
expect(Dotenv::Railtie.instance.send(:dotenv_files)).to eql(
[
Rails.root.join(".env.test.local"),
Rails.root.join(".env.local"),
Rails.root.join(".env.test"),
Rails.root.join(".env")
]
)
end

it "does load .env.local in development environment" do
it "loads .env.local in development environment" do
Rails.env = "development"
expect(Dotenv::Railtie.instance.send(:dotenv_files)).to eql(
[
Expand All @@ -113,7 +115,7 @@ def add(*items)
)
end

it "overloads .env.test with .env" do
it "overloads .env.local with .env" do
expect(ENV["DOTENV"]).to eql("true")
end

Expand Down

0 comments on commit ec2c601

Please sign in to comment.