Skip to content

Commit 90a9715

Browse files
committed
Merge pull request #9080 from sikachu/master-rails-test
Add `rails test` command to run the test suite
2 parents 8fc3915 + 3ed41e5 commit 90a9715

File tree

8 files changed

+591
-132
lines changed

8 files changed

+591
-132
lines changed

guides/source/testing.md

Lines changed: 59 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
A Guide to Testing Rails Applications
22
=====================================
33

4-
This guide covers built-in mechanisms offered by Rails to test your
5-
application.
4+
This guide covers built-in mechanisms in Rails for testing your application.
65

76
After reading this guide, you will know:
87

@@ -38,11 +37,11 @@ Rails creates a `test` folder for you as soon as you create a Rails project usin
3837

3938
```bash
4039
$ ls -F test
41-
42-
fixtures/ functional/ integration/ test_helper.rb unit/
40+
controllers/ helpers/ mailers/ test_helper.rb
41+
fixtures/ integration/ models/
4342
```
4443

45-
The `unit` directory is meant to hold tests for your models, the `functional` directory is meant to hold tests for your controllers and the `integration` directory is meant to hold tests that involve any number of controllers interacting.
44+
The `models` directory is meant to hold tests for your models, the `controllers` directory is meant to hold tests for your controllers and the `integration` directory is meant to hold tests that involve any number of controllers interacting.
4645

4746
Fixtures are a way of organizing test data; they reside in the `fixtures` folder.
4847

@@ -140,10 +139,9 @@ The default test stub in `test/models/post_test.rb` looks like this:
140139
require 'test_helper'
141140

142141
class PostTest < ActiveSupport::TestCase
143-
# Replace this with your real tests.
144-
test "the truth" do
145-
assert true
146-
end
142+
# test "the truth" do
143+
# assert true
144+
# end
147145
end
148146
```
149147

@@ -224,34 +222,30 @@ TIP: You can see all these rake tasks and their descriptions by running `rake --
224222

225223
### Running Tests
226224

227-
Running a test is as simple as invoking the file containing the test cases through Ruby:
225+
Running a test is as simple as invoking the file containing the test cases through `rails test` command.
228226

229227
```bash
230-
$ ruby -Itest test/models/post_test.rb
231-
232-
Loaded suite models/post_test
233-
Started
228+
$ rails test test/models/post_test.rb
234229
.
235-
Finished in 0.023513 seconds.
236230

237-
1 tests, 1 assertions, 0 failures, 0 errors
238-
```
231+
Finished tests in 0.009262s, 107.9680 tests/s, 107.9680 assertions/s.
239232

240-
This will run all the test methods from the test case. Note that `test_helper.rb` is in the `test` directory, hence this directory needs to be added to the load path using the `-I` switch.
233+
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
234+
```
241235

242-
You can also run a particular test method from the test case by using the `-n` switch with the `test method name`.
236+
You can also run a particular test method from the test case by running the test and using `-n` switch with the `test method name`.
243237

244238
```bash
245-
$ ruby -Itest test/models/post_test.rb -n test_the_truth
246-
247-
Loaded suite models/post_test
248-
Started
239+
$ rails test test/models/post_test.rb -n test_the_truth
249240
.
250-
Finished in 0.023513 seconds.
251241

252-
1 tests, 1 assertions, 0 failures, 0 errors
242+
Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
243+
244+
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
253245
```
254246

247+
This will run all test methods from the test case. Note that `test_helper.rb` is in the `test` directory, hence this directory needs to be added to the load path using the `-I` switch.
248+
255249
The `.` (dot) above indicates a passing test. When a test fails you see an `F`; when a test throws an error you see an `E` in its place. The last line of the output is the summary.
256250

257251
To see how a test failure is reported, you can add a failing test to the `post_test.rb` test case.
@@ -266,17 +260,16 @@ end
266260
Let us run this newly added test.
267261

268262
```bash
269-
$ ruby unit/post_test.rb -n test_should_not_save_post_without_title
270-
Loaded suite -e
271-
Started
263+
$ rails test test/models/post_test.rb -n test_should_not_save_post_without_title
272264
F
273-
Finished in 0.102072 seconds.
265+
266+
Finished tests in 0.044632s, 22.4054 tests/s, 22.4054 assertions/s.
274267

275268
1) Failure:
276-
test_should_not_save_post_without_title(PostTest) [/test/models/post_test.rb:6]:
277-
<false> is not true.
269+
test_should_not_save_post_without_title(PostTest) [test/models/post_test.rb:6]:
270+
Failed assertion, no message given.
278271

279-
1 tests, 1 assertions, 1 failures, 0 errors
272+
1 tests, 1 assertions, 1 failures, 0 errors, 0 skips
280273
```
281274

282275
In the output, `F` denotes a failure. You can see the corresponding trace shown under `1)` along with the name of the failing test. The next few lines contain the stack trace followed by a message which mentions the actual value and the expected value by the assertion. The default assertion messages provide just enough information to help pinpoint the error. To make the assertion failure message more readable, every assertion provides an optional message parameter, as shown here:
@@ -292,9 +285,8 @@ Running this test shows the friendlier assertion message:
292285

293286
```bash
294287
1) Failure:
295-
test_should_not_save_post_without_title(PostTest) [/test/models/post_test.rb:6]:
296-
Saved the post without a title.
297-
<false> is not true.
288+
test_should_not_save_post_without_title(PostTest) [test/models/post_test.rb:6]:
289+
Saved the post without a title
298290
```
299291

300292
Now to get this test to pass we can add a model level validation for the _title_ field.
@@ -308,13 +300,12 @@ end
308300
Now the test should pass. Let us verify by running the test again:
309301

310302
```bash
311-
$ ruby unit/post_test.rb -n test_should_not_save_post_without_title
312-
Loaded suite unit/post_test
313-
Started
303+
$ rails test test/models/post_test.rb -n test_should_not_save_post_without_title
314304
.
315-
Finished in 0.193608 seconds.
316305

317-
1 tests, 1 assertions, 0 failures, 0 errors
306+
Finished tests in 0.047721s, 20.9551 tests/s, 20.9551 assertions/s.
307+
308+
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
318309
```
319310

320311
Now, if you noticed, we first wrote a test which fails for a desired functionality, then we wrote some code which adds the functionality and finally we ensured that our test passes. This approach to software development is referred to as _Test-Driven Development_ (TDD).
@@ -334,18 +325,17 @@ end
334325
Now you can see even more output in the console from running the tests:
335326

336327
```bash
337-
$ ruby unit/post_test.rb -n test_should_report_error
338-
Loaded suite -e
339-
Started
328+
$ rails test test/models/post_test.rb -n test_should_report_error
340329
E
341-
Finished in 0.082603 seconds.
330+
331+
Finished tests in 0.030974s, 32.2851 tests/s, 0.0000 assertions/s.
342332

343333
1) Error:
344334
test_should_report_error(PostTest):
345-
NameError: undefined local variable or method `some_undefined_variable' for #<PostTest:0x249d354>
346-
/test/models/post_test.rb:6:in `test_should_report_error'
335+
NameError: undefined local variable or method `some_undefined_variable' for #<PostTest:0x007fe32e24afe0>
336+
test/models/post_test.rb:10:in `block in <class:PostTest>'
347337
348-
1 tests, 0 assertions, 0 failures, 1 errors
338+
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
349339
```
350340

351341
Notice the 'E' in the output. It denotes a test with error.
@@ -642,12 +632,9 @@ Here's what a freshly-generated integration test looks like:
642632
require 'test_helper'
643633
644634
class UserFlowsTest < ActionDispatch::IntegrationTest
645-
fixtures :all
646-
647-
# Replace this with your real tests.
648-
test "the truth" do
649-
assert true
650-
end
635+
# test "the truth" do
636+
# assert true
637+
# end
651638
end
652639
```
653640
@@ -755,23 +742,28 @@ end
755742
Rake Tasks for Running your Tests
756743
---------------------------------
757744
758-
You don't need to set up and run your tests by hand on a test-by-test basis. Rails comes with a number of rake tasks to help in testing. The table below lists all rake tasks that come along in the default Rakefile when you initiate a Rails project.
745+
You don't need to set up and run your tests by hand on a test-by-test basis. Rails comes with a number of commands to help in testing. The table below lists all commands that come along in the default Rakefile when you initiate a Rails project.
746+
747+
| Tasks | Description |
748+
| ------------------------ | ----------- |
749+
| `rails test` | Runs all unit, functional and integration tests. You can also simply run `rails test` as Rails will run all the tests by default|
750+
| `rails test controllers` | Runs all the controller tests from `test/controllers`|
751+
| `rails test functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional`|
752+
| `rails test helpers` | Runs all the helper tests from `test/helpers`|
753+
| `rails test integration` | Runs all the integration tests from `test/integration`|
754+
| `rails test mailers` | Runs all the mailer tests from `test/mailers`|
755+
| `rails test models` | Runs all the model tests from `test/models`|
756+
| `rails test units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit`|
759757
760-
| Tasks | Description |
761-
| ------------------------------- | ----------- |
762-
| `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake` as the _test_ target is the default.|
763-
| `rake test:controllers` | Runs all the controller tests from `test/controllers`|
764-
| `rake test:functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional`|
765-
| `rake test:helpers` | Runs all the helper tests from `test/helpers`|
766-
| `rake test:integration` | Runs all the integration tests from `test/integration`|
767-
| `rake test:mailers` | Runs all the mailer tests from `test/mailers`|
768-
| `rake test:models` | Runs all the model tests from `test/models`|
769-
| `rake test:recent` | Tests recent changes|
770-
| `rake test:uncommitted` | Runs all the tests which are uncommitted. Supports Subversion and Git|
771-
| `rake test:units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit`|
758+
There're also some test commands which you can initiate by running rake tasks:
772759
760+
| Tasks | Description |
761+
| ------------------------ | ----------- |
762+
| `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake` as the _test_ target is the default.|
763+
| `rake test:recent` | Tests recent changes|
764+
| `rake test:uncommitted` | Runs all the tests which are uncommitted. Supports Subversion and Git|
773765
774-
Brief Note About `Test::Unit`
766+
Brief Note About `MiniTest`
775767
-----------------------------
776768
777769
Ruby ships with a boat load of libraries. Ruby 1.8 provides `Test::Unit`, a framework for unit testing in Ruby. All the basic assertions discussed above are actually defined in `Test::Unit::Assertions`. The class `ActiveSupport::TestCase` which we have been using in our unit and functional tests extends `Test::Unit::TestCase`, allowing

railties/CHANGELOG.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,38 @@
1919

2020
*Terence Lee*
2121

22+
* Rails now generates a `test/test_helper.rb` file with `fixtures :all` commented out by default,
23+
since we don't want to force loading all fixtures for user when a single test is run. However,
24+
fixtures are still going to be loaded automatically for test suites.
25+
26+
To force all fixtures to be create in your database, use `rails test -f` to run your test.
27+
28+
*Prem Sichanugrist*
29+
30+
* Add `rails test` command for running tests
31+
32+
To run all tests:
33+
34+
$ rails test
35+
36+
To run a test suite
37+
38+
$ rails test [models,helpers,units,controllers,mailers,...]
39+
40+
To run a selected test file(s):
41+
42+
$ rails test test/unit/foo_test.rb [test/unit/bar_test.rb ...]
43+
44+
To run a single test from a test file
45+
46+
$ rails test test/unit/foo_test.rb -n test_the_truth
47+
48+
For more information, see `rails test --help`.
49+
50+
This command will eventually replace `rake test:*` and `rake test` tasks
51+
52+
*Prem Sichanugrist and Chris Toomey*
53+
2254
* Add notice message for destroy action in scaffold generator.
2355

2456
*Rahul P. Chaudhari*

railties/lib/rails/commands.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"d" => "destroy",
66
"c" => "console",
77
"s" => "server",
8+
"t" => "test",
89
"db" => "dbconsole",
910
"r" => "runner"
1011
}
@@ -16,6 +17,7 @@
1617
generate Generate new code (short-cut alias: "g")
1718
console Start the Rails console (short-cut alias: "c")
1819
server Start the Rails server (short-cut alias: "s")
20+
test Running the test file (short-cut alias: "t")
1921
dbconsole Start a console for the database specified in config/database.yml
2022
(short-cut alias: "db")
2123
new Create a new Rails application. "rails new my_app" creates a
@@ -78,6 +80,15 @@
7880
server.start
7981
end
8082

83+
when 'test'
84+
$LOAD_PATH.unshift("./test")
85+
require 'rails/commands/test_runner'
86+
options = Rails::TestRunner.parse_arguments(ARGV)
87+
ENV['RAILS_ENV'] ||= options[:environment] || 'test'
88+
89+
require APP_PATH
90+
Rails::TestRunner.start(ARGV, options)
91+
8192
when 'dbconsole'
8293
require 'rails/commands/dbconsole'
8394
Rails::DBConsole.start

0 commit comments

Comments
 (0)