提交 b4df2536 编写于 作者: P Prem Sichanugrist and Chris Toomey 提交者: Prem Sichanugrist

Add `rails test` command to run the test suite

To run the whole test suite:

    $ rails test

To run the test file(s):

    $ rails test test/unit/foo_test.rb [test/unit/bar_test.rb ...]

To run the test suite

    $ rails test [models,helpers,units,controllers,mailers,...]

For more information, see `rails test --help`.

This command will eventually replacing `rake test:*`, and `rake test`
command will actually invoking `rails test` instead.
上级 15970efb
......@@ -19,6 +19,27 @@
*Terence Lee*
* Add `rails test` command to run the test suite
To run the whole test suite:
$ rails test
To run the test file(s):
$ rails test test/unit/foo_test.rb [test/unit/bar_test.rb ...]
To run the test suite
$ rails test [models,helpers,units,controllers,mailers,...]
For more information, see `rails test --help`.
This command will eventually replacing `rake test:*`, and `rake test`
command will actually invoking `rails test` instead.
*Prem Sichanugrist and Chris Toomey*
* Add notice message for destroy action in scaffold generator.
*Rahul P. Chaudhari*
......
......@@ -5,6 +5,7 @@
"d" => "destroy",
"c" => "console",
"s" => "server",
"t" => "test",
"db" => "dbconsole",
"r" => "runner"
}
......@@ -16,6 +17,7 @@
generate Generate new code (short-cut alias: "g")
console Start the Rails console (short-cut alias: "c")
server Start the Rails server (short-cut alias: "s")
test Running the test file (short-cut alias: "t")
dbconsole Start a console for the database specified in config/database.yml
(short-cut alias: "db")
new Create a new Rails application. "rails new my_app" creates a
......@@ -78,6 +80,19 @@
server.start
end
when 'test'
$LOAD_PATH.unshift("./test")
require 'rails/commands/test_runner'
if ["-h", "--help"].include?(ARGV.first)
Rails::TestRunner.help_message
exit
else
require APP_PATH
Rails.application.require_environment!
Rails.application.load_tasks
Rails::TestRunner.start(ARGV)
end
when 'dbconsole'
require 'rails/commands/dbconsole'
Rails::DBConsole.start
......
require 'optparse'
require 'minitest/unit'
module Rails
# Handling the all the logic behind +rails test+ command.
class TestRunner
class << self
# Parse the test suite name from the arguments array and pass in a list
# of file to a new +TestRunner+ object, then invoke the evaluation. If
# the argument is not a test suite name, it will be treated as a file
# name and passed to the +TestRunner+ instance right away.
def start(arguments)
case arguments.first
when nil
new(Dir['test/**/*_test.rb']).run
when 'models'
new(Dir['test/models/**/*_test.rb']).run
when 'helpers'
new(Dir['test/helpers/**/*_test.rb']).run
when 'units'
new(Dir['test/{models,helpers,unit}/**/*_test.rb']).run
when 'controllers'
new(Dir['test/controllers/**/*_test.rb']).run
when 'mailers'
new(Dir['test/mailers/**/*_test.rb']).run
when 'functionals'
new(Dir['test/{controllers,mailers,functional}/**/*_test.rb']).run
when 'integration'
new(Dir['test/integration/**/*_test.rb']).run
else
new(arguments).run
end
end
# Print out the help message which listed all of the test suite names.
def help_message
puts "Usage: rails test [path to test file(s) or test suite type]"
puts ""
puts "Run single test file, or a test suite, under Rails'"
puts "environment. If the file name(s) or suit name is omitted,"
puts "Rails will run all the test suites."
puts ""
puts "Support types of test suites:"
puts "-------------------------------------------------------------"
puts "* models (test/models/**/*)"
puts "* helpers (test/helpers/**/*)"
puts "* units (test/{models,helpers,unit}/**/*"
puts "* controllers (test/controllers/**/*)"
puts "* mailers (test/mailers/**/*)"
puts "* functionals (test/{controllers,mailers,functional}/**/*)"
puts "* integration (test/integration/**/*)"
puts "-------------------------------------------------------------"
end
end
# Create a new +TestRunner+ object with a list of test file paths.
def initialize(files)
@files = files
Rake::Task['test:prepare'].invoke
MiniTest::Unit.output = SilentUntilSyncStream.new(MiniTest::Unit.output)
end
# Run the test files by evaluate each of them.
def run
@files.each { |filename| load(filename) }
end
# A null stream object which ignores everything until +sync+ has been set
# to true. This is only to be used to silence unnecessary output from
# MiniTest, as MiniTest calls +output.sync = true+ right before output the
# first test result.
class SilentUntilSyncStream < File
# Create a +SilentUntilSyncStream+ object by given a stream object that
# this stream should set +MiniTest::Unit.output+ to after +sync+ has been
# set to true.
def initialize(target_stream)
@target_stream = target_stream
super(File::NULL, 'w')
end
# Swap +MiniTest::Unit.output+ to another stream when +sync+ is true.
def sync=(sync)
if sync
@target_stream.sync = true
MiniTest::Unit.output = @target_stream
end
super
end
end
end
end
require 'isolation/abstract_unit'
module ApplicationTests
class TestRunnerTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
def setup
build_app
create_schema
end
def teardown
teardown_app
end
def test_should_not_display_heading
create_test_file
run_test_command.tap do |output|
assert_no_match /Run options:/, output
assert_no_match /Running tests:/, output
end
end
def test_run_shortcut
create_test_file :models, 'foo'
output = Dir.chdir(app_path) { `bundle exec rails t test/models/foo_test.rb` }
assert_match /1 tests, 1 assertions, 0 failures/, output
end
def test_run_single_file
create_test_file :models, 'foo'
assert_match /1 tests, 1 assertions, 0 failures/, run_test_command("test/models/foo_test.rb")
end
def test_run_multiple_files
create_test_file :models, 'foo'
create_test_file :models, 'bar'
assert_match /2 tests, 2 assertions, 0 failures/, run_test_command("test/models/foo_test.rb test/models/bar_test.rb")
end
def test_run_file_with_syntax_error
app_file 'test/models/error_test.rb', <<-RUBY
require 'test_helper'
def; end
RUBY
error_stream = Tempfile.new('error')
redirect_stderr(error_stream) { run_test_command('test/models/error_test.rb') }
assert_match /SyntaxError/, error_stream.read
end
def test_invoke_rake_test_prepare
app_file "lib/tasks/test.rake", <<-RUBY
namespace :test do
task :prepare do
puts "Hello World"
end
end
RUBY
create_test_file
assert_match /Hello World/, run_test_command
end
def test_run_models
create_test_file :models, 'foo'
create_test_file :models, 'bar'
create_test_file :controllers, 'foobar_controller'
run_test_command("models").tap do |output|
assert_match /FooTest/, output
assert_match /BarTest/, output
assert_match /2 tests, 2 assertions, 0 failures/, output
end
end
def test_run_helpers
create_test_file :helpers, 'foo_helper'
create_test_file :helpers, 'bar_helper'
create_test_file :controllers, 'foobar_controller'
run_test_command('helpers').tap do |output|
assert_match /FooHelperTest/, output
assert_match /BarHelperTest/, output
assert_match /2 tests, 2 assertions, 0 failures/, output
end
end
def test_run_units
create_test_file :models, 'foo'
create_test_file :helpers, 'bar_helper'
create_test_file :unit, 'baz_unit'
create_test_file :controllers, 'foobar_controller'
run_test_command('units').tap do |output|
assert_match /FooTest/, output
assert_match /BarHelperTest/, output
assert_match /BazUnitTest/, output
assert_match /3 tests, 3 assertions, 0 failures/, output
end
end
def test_run_controllers
create_test_file :controllers, 'foo_controller'
create_test_file :controllers, 'bar_controller'
create_test_file :models, 'foo'
run_test_command('controllers').tap do |output|
assert_match /FooControllerTest/, output
assert_match /BarControllerTest/, output
assert_match /2 tests, 2 assertions, 0 failures/, output
end
end
def test_run_mailers
create_test_file :mailers, 'foo_mailer'
create_test_file :mailers, 'bar_mailer'
create_test_file :models, 'foo'
run_test_command('mailers').tap do |output|
assert_match /FooMailerTest/, output
assert_match /BarMailerTest/, output
assert_match /2 tests, 2 assertions, 0 failures/, output
end
end
def test_run_functionals
create_test_file :mailers, 'foo_mailer'
create_test_file :controllers, 'bar_controller'
create_test_file :functional, 'baz_functional'
create_test_file :models, 'foo'
run_test_command('functionals').tap do |output|
assert_match /FooMailerTest/, output
assert_match /BarControllerTest/, output
assert_match /BazFunctionalTest/, output
assert_match /3 tests, 3 assertions, 0 failures/, output
end
end
def test_run_integration
create_test_file :integration, 'foo_integration'
create_test_file :models, 'foo'
run_test_command('integration').tap do |output|
assert_match /FooIntegration/, output
assert_match /1 tests, 1 assertions, 0 failures/, output
end
end
def test_run_whole_suite
types = [:models, :helpers, :unit, :controllers, :mailers, :functional, :integration]
types.each { |type| create_test_file type, "foo_#{type}" }
run_test_command('') .tap do |output|
types.each { |type| assert_match /Foo#{type.to_s.camelize}Test/, output }
assert_match /7 tests, 7 assertions, 0 failures/, output
end
end
private
def run_test_command(arguments = 'test/unit/test_test.rb')
Dir.chdir(app_path) { `bundle exec rails test #{arguments}` }
end
def create_schema
app_file 'db/schema.rb', ''
end
def redirect_stderr(target_stream)
previous_stderr = STDERR.dup
$stderr.reopen(target_stream)
yield
target_stream.rewind
ensure
$stderr = previous_stderr
end
def create_test_file(path = :unit, name = 'test')
app_file "test/#{path}/#{name}_test.rb", <<-RUBY
require 'test_helper'
class #{name.camelize}Test < ActiveSupport::TestCase
def test_truth
puts "#{name.camelize}Test"
assert true
end
end
RUBY
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册