Permalink
Browse files

Drop the idea that we can run tests in the same session by switching …

…back and forth between envs. Too hard. Just run a separate console for testing
  • Loading branch information...
1 parent 3515f3d commit 7f7852faf579b9cc3981404956588c08ea3537d1 @dhh dhh committed Dec 23, 2012
Showing with 29 additions and 28 deletions.
  1. +7 −2 README.md
  2. +10 −1 lib/rails/commands/console_delegation.rb
  3. +12 −25 lib/rails/commands/test_environment.rb
View
@@ -1,7 +1,7 @@
Commands
========
-Run Rake and Rails commands during a console session. This side-steps the need to load the entire environment over and over again when you run these commands from the shell. This constant reloading of the environment is what causes slow boot time on big applications. Think of this like a baby Zeus or the Turbolinks of commands.
+Run Rake and Rails commands during a development console session and run tests during a test console session. This side-steps the need to load the entire environment over and over again when you run these commands from the shell. This constant reloading of the environment is what causes slow boot time on big applications. Think of this like a baby Zeus or the Turbolinks of commands.
Installation
@@ -18,10 +18,15 @@ And then execute:
Usage
-----
-When your console boots, it'll automatically have a `commander` object instantiated. The following methods are delegated to this object: rake, test, generate, destroy, update. It's used like this:
+When your console boots, it'll automatically have a `commander` object instantiated. The following methods are delegated to this object: rake, generate, destroy, update. It's used like this:
> generate "scaffold post title:string"
> rake "db:migrate"
+
+To use a persistent console for testing, be sure to first start it in the test environment, like so `./script/rails console test`. Then you can run tests like this:
+
+ > test "models"
+ > test "controllers"
> test "models/person"
You can see the options available for all the commands by running them with no parameters.
@@ -7,7 +7,16 @@ def commander
@commander ||= Commander.new
end
- delegate :rake, :test, :generate, :destroy, :update, to: :commander
+ def test(*args)
+ if Rails.env.test?
+ commander.test(*args)
+ else
+ puts "You can only run tests in a console started in the test environment. " +
+ "Use `./script/rails console test` to start such a console"
+ end
+ end
+
+ delegate :rake, :generate, :destroy, :update, to: :commander
end
end
end
@@ -7,52 +7,39 @@ module TestEnvironment
def fork
Environment.fork do
- switch_to_test
+ setup_for_test
yield
end
+
+ reset_active_record
end
private
- def switch_to_test
- switch_rails
- switch_bundler
-
- reset_active_record
- reload_classes
-
+ def setup_for_test
+ reload_classes
add_test_dir_to_load_path
end
- def switch_rails
- ENV['RAILS_ENV'] = Rails.env = "test"
-
- Kernel.silence_warnings do
- load Rails.root.join('config', 'environments', "test.rb")
- Dir[Rails.root.join('config', 'initializers', '*.rb')].map { |file| load file }
- end
- end
-
- def switch_bundler
- Bundler.require "test"
- end
-
-
def reload_classes
+ # Overwrite the default config.cache_classes = true,
+ # so we can change classes in the test session.
+ ActiveSupport::Dependencies.mechanism = :load
+
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader.prepare!
end
-
+
def reset_active_record
if defined? ActiveRecord
ActiveRecord::Base.clear_active_connections!
ActiveRecord::Base.establish_connection
end
end
-
def add_test_dir_to_load_path
- $:.unshift("./test")
+ test_path = Rails.root.join("test")
+ $:.unshift(test_path) unless $:.first == test_path
end
end
end

5 comments on commit 7f7852f

Contributor

gbuesing replied Dec 23, 2012

I'm getting this to work by forking the test environment as a child process before loading the console: https://gist.github.com/4365756

Owner

fxn replied Dec 23, 2012

Good approach.

Owner

dhh replied Dec 23, 2012

Contributor

gbuesing replied Dec 24, 2012

Updated gist loads gems before forking, to minimize load time, as per suggestion by @dhh : https://gist.github.com/4365756

Contributor

gbuesing replied Dec 27, 2012

Made this into a gem: https://github.com/gbuesing/duoconsole

I had to create a separate executable to launch the console, b/c there was no way to patch the proper behavior into the existing rails console command.

Please sign in to comment.