Skip to content

Force RAILS_ENV=test in spec/rails_helper.rb so specs never use the dev database - #148

Open
eastagiletracker wants to merge 1 commit into
apsislabs:mainfrom
eastagiletracker:agile-board/force-test-env-in-specs
Open

eastagiletracker wants to merge 1 commit into
apsislabs:mainfrom
eastagiletracker:agile-board/force-test-env-in-specs

Conversation

@eastagiletracker

Copy link
Copy Markdown

This PR proposes forcing RAILS_ENV=test in spec/rails_helper.rb so the spec suite always runs against the test database and never falls back to development. We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/270. You can sign in with your GitHub ID to claim ownership of the project.

Fixes #83.

What's wrong

spec/rails_helper.rb selects the environment with ENV["RAILS_ENV"] ||= "test". That only defaults to test when RAILS_ENV is unset — if a value is already present in the shell (a common RAILS_ENV=development, a .env, or a CI variable) it is honored instead. The only guard below it aborts on production, not on development:

ENV["RAILS_ENV"] ||= "test"
require File.expand_path("../config/environment", __dir__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?

Because config/database.yml maps development to the primary app database and only test to app_test, booting the suite in development points ActiveRecord::Migration.maintain_test_schema! and the transactional fixtures at the developer's development database — which can wipe real data. This is the behavior issue #83 asks to close ("RAILS_ENV=test should be the default and we should not fall back to development").

Reproduce on main

Running the suite with a RAILS_ENV=development inherited from the shell boots in development and connects to the app (development) database rather than app_test:

$ RAILS_ENV=development bundle exec ruby -e 'ENV["RAILS_ENV"] ||= "test"; require_relative "config/environment"; puts "resolved Rails.env = #{Rails.env}"; puts "primary database = #{ActiveRecord::Base.connection_db_config.database}"'
resolved Rails.env = development
primary database = app

The fix

Force the environment so the value inherited from the shell can never redirect the suite:

ENV["RAILS_ENV"] = "test"

Normal invocations (rspec, bin/run_tests) are unchanged — they don't set RAILS_ENV, so test was and remains the effective environment. The only behavior change is that a leaked non-test RAILS_ENV now resolves to test instead of silently running against the wrong database, which is the intended safety guarantee. This complements the earlier compose.yml change (d5ea3ff) that stopped the container from defaulting RAILS_ENV to development, closing the same gap at the spec-helper layer regardless of how RAILS_ENV is set.

Verification

I added spec/rails_helper_env_spec.rb, a regression test asserting the suite runs in the test environment and connects to a _test database. It fails on the current tree and passes with the fix, run with a leaked RAILS_ENV=development:

# before (on main, with the fix reverted):
$ RAILS_ENV=development bundle exec rspec spec/rails_helper_env_spec.rb
  1) spec environment always runs in the test environment
     Failure/Error: expect(Rails.env.test?).to be(true)
       expected true
            got false
  2) spec environment connects to a test database
     Failure/Error: expect(database).to end_with("_test")
       expected "app" to end with "_test"
2 examples, 2 failures

# after (with the fix):
$ RAILS_ENV=development bundle exec rspec spec/rails_helper_env_spec.rb
2 examples, 0 failures

The full suite stays green and rubocop (standard + rubocop-rspec) reports no offenses on the changed files:

$ bundle exec rspec
4 examples, 0 failures, 2 pending
$ bundle exec rubocop spec/rails_helper.rb spec/rails_helper_env_spec.rb
2 files inspected, no offenses detected

One heads-up for merge order: the open PR #138 also edits spec/rails_helper.rb, but on different lines (support-file loading and Devise/Shoulda config), so this one-line change to the environment guard should apply cleanly alongside it.

How this was managed

We imported your issues and pull requests into a live agile board and used it to manage this work. This change is tracked on its own story at https://eastagiletracker.com/projects/270/stories/159506, on the board at https://eastagiletracker.com/projects/270.

board

If you'd rather not receive contributions like this, reply no-more-prs on this pull request and we won't open any further ones on your repositories.


Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com

spec/rails_helper.rb set the Rails environment with ENV["RAILS_ENV"] ||= "test",
which honors any RAILS_ENV already present in the shell. When RAILS_ENV=development
is set, the suite boots in development and maintain_test_schema! plus the
transactional fixtures operate on the development database instead of app_test,
which can wipe real data.

Force ENV["RAILS_ENV"] = "test" so specs always run against the test database
regardless of the inherited environment, and add a regression spec covering it.
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.

Verify specs always use Test DB

1 participant