aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2017-12-06 17:33:16 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2017-12-06 20:40:04 -0800
commitda225c0db640aec1df0920e86c1eb4ca35d82073 (patch)
tree3b69e271902ff2a32ed83df3e860360d1fe7c191
parent0ba5615e403e9f44c775633dc2a1275a1e971390 (diff)
downloadrails-da225c0db640aec1df0920e86c1eb4ca35d82073.tar.gz
rails-da225c0db640aec1df0920e86c1eb4ca35d82073.tar.bz2
rails-da225c0db640aec1df0920e86c1eb4ca35d82073.zip
Fix Rails environment when running tests with Ruby
I frequently run tests with `ruby`, not with a runner like `rake` or `rails`. When running the test with just `ruby` the `RAILS_ENV` environment variable did not get set to "test", and this would cause the tests to fail (and even mutate the development database!) This commit adds integration tests for running tests with just `ruby` and ensures the environment gets defaulted to "test". I also added a test to ensure that passing an environment to `-e` actually works (and fixed that case too). An interesting / annoying thing is that Minitest picks up it's plugins by asking RubyGems for a list of files: https://github.com/seattlerb/minitest/blob/ca6a71ca901016db09a5ad466b4adea4b52a504a/lib/minitest.rb#L92-L100 This means that RubyGems needs to somehow know about the file before it can return it to Minitest. Since we are not packaging Rails as a Gem before running the integration tests on it (duh, why would you do that?), RubyGems doesn't know about the file, so it can't tell Minitest, so Minitest doesn't automatically require it. This means I had to manually require and insert the plugin in our integration test. I've left comments about that in the test as well. Ugh.
-rw-r--r--railties/lib/rails/test_unit/runner.rb5
-rw-r--r--railties/test/application/test_runner_test.rb56
-rw-r--r--railties/test/isolation/abstract_unit.rb6
3 files changed, 64 insertions, 3 deletions
diff --git a/railties/lib/rails/test_unit/runner.rb b/railties/lib/rails/test_unit/runner.rb
index 5c2f6451e2..45e8472f6a 100644
--- a/railties/lib/rails/test_unit/runner.rb
+++ b/railties/lib/rails/test_unit/runner.rb
@@ -12,8 +12,11 @@ module Rails
class << self
def attach_before_load_options(opts)
+ ENV["RAILS_ENV"] = "test"
opts.on("--warnings", "-w", "Run with Ruby warnings enabled") {}
- opts.on("--environment", "-e", "Run tests in the ENV environment") {}
+ opts.on("-e", "--environment ENV", "Run tests in the ENV environment") { |e|
+ ENV["RAILS_ENV"] = e
+ }
end
def parse_options(argv)
diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb
index e92a0466dd..27983c3b55 100644
--- a/railties/test/application/test_runner_test.rb
+++ b/railties/test/application/test_runner_test.rb
@@ -569,6 +569,26 @@ module ApplicationTests
assert_match "AccountTest#test_truth", output, "passing TEST= should run selected test"
end
+ def test_running_with_ruby_gets_test_env_by_default
+ file = create_test_for_env("test")
+ results = Dir.chdir(app_path) {
+ `ruby -Ilib:test #{file}`.each_line.map { |line| JSON.parse line }
+ }
+ assert_equal 1, results.length
+ failures = results.first["failures"]
+ flunk(failures.first) unless failures.empty?
+ end
+
+ def test_running_with_ruby_can_set_env_via_cmdline
+ file = create_test_for_env("development")
+ results = Dir.chdir(app_path) {
+ `ruby -Ilib:test #{file} -e development`.each_line.map { |line| JSON.parse line }
+ }
+ assert_equal 1, results.length
+ failures = results.first["failures"]
+ flunk(failures.first) unless failures.empty?
+ end
+
def test_rake_passes_multiple_TESTOPTS_to_minitest
create_test_file :models, "account"
output = Dir.chdir(app_path) { `bin/rake test TESTOPTS='-v --seed=1234'` }
@@ -727,6 +747,42 @@ module ApplicationTests
app_file "db/schema.rb", ""
end
+ def create_test_for_env(env)
+ app_file "test/models/environment_test.rb", <<-RUBY
+ require 'test_helper'
+ class JSONReporter < Minitest::AbstractReporter
+ def record(result)
+ puts JSON.dump(klass: result.class.name,
+ name: result.name,
+ failures: result.failures,
+ assertions: result.assertions,
+ time: result.time)
+ end
+ end
+
+ def Minitest.plugin_json_reporter_init(opts)
+ Minitest.reporter.reporters.clear
+ Minitest.reporter.reporters << JSONReporter.new
+ end
+
+ Minitest.extensions << "rails"
+ Minitest.extensions << "json_reporter"
+
+ # Minitest uses RubyGems to find plugins, and since RubyGems
+ # doesn't know about the Rails installation we're pointing at,
+ # Minitest won't require the Rails minitest plugin when we run
+ # these integration tests. So we have to manually require the
+ # Minitest plugin here.
+ require 'minitest/rails_plugin'
+
+ class EnvironmentTest < ActiveSupport::TestCase
+ def test_environment
+ assert_equal #{env.dump}, ENV["RAILS_ENV"]
+ end
+ end
+ RUBY
+ end
+
def create_test_file(path = :unit, name = "test", pass: true)
app_file "test/#{path}/#{name}_test.rb", <<-RUBY
require 'test_helper'
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 5b1c06d4e5..96c6f21395 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -358,10 +358,12 @@ module TestHelpers
end
def app_file(path, contents, mode = "w")
- FileUtils.mkdir_p File.dirname("#{app_path}/#{path}")
- File.open("#{app_path}/#{path}", mode) do |f|
+ file_name = "#{app_path}/#{path}"
+ FileUtils.mkdir_p File.dirname(file_name)
+ File.open(file_name, mode) do |f|
f.puts contents
end
+ file_name
end
def remove_file(path)