rails 4.0.0 → 4.2.11.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +30 -23
  3. data/guides/CHANGELOG.md +108 -6
  4. data/guides/Rakefile +21 -6
  5. data/guides/assets/images/akshaysurve.jpg +0 -0
  6. data/guides/assets/images/edge_badge.png +0 -0
  7. data/guides/assets/images/feature_tile.gif +0 -0
  8. data/guides/assets/images/footer_tile.gif +0 -0
  9. data/guides/assets/images/fxn.png +0 -0
  10. data/guides/assets/images/getting_started/article_with_comments.png +0 -0
  11. data/guides/assets/images/getting_started/challenge.png +0 -0
  12. data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
  13. data/guides/assets/images/getting_started/forbidden_attributes_for_new_article.png +0 -0
  14. data/guides/assets/images/getting_started/form_with_errors.png +0 -0
  15. data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
  16. data/guides/assets/images/getting_started/new_article.png +0 -0
  17. data/guides/assets/images/getting_started/rails_welcome.png +0 -0
  18. data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
  19. data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
  20. data/guides/assets/images/getting_started/show_action_for_articles.png +0 -0
  21. data/guides/assets/images/getting_started/template_is_missing_articles_new.png +0 -0
  22. data/guides/assets/images/getting_started/unknown_action_create_for_articles.png +0 -0
  23. data/guides/assets/images/getting_started/unknown_action_new_for_articles.png +0 -0
  24. data/guides/assets/images/header_tile.gif +0 -0
  25. data/guides/assets/images/icons/README +1 -1
  26. data/guides/assets/images/icons/callouts/11.png +0 -0
  27. data/guides/assets/images/icons/callouts/12.png +0 -0
  28. data/guides/assets/images/icons/callouts/13.png +0 -0
  29. data/guides/assets/images/icons/callouts/15.png +0 -0
  30. data/guides/assets/images/icons/caution.png +0 -0
  31. data/guides/assets/images/icons/example.png +0 -0
  32. data/guides/assets/images/radar.png +0 -0
  33. data/guides/assets/images/rails4_features.png +0 -0
  34. data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
  35. data/guides/assets/images/vijaydev.jpg +0 -0
  36. data/guides/assets/javascripts/guides.js +36 -34
  37. data/guides/assets/stylesheets/main.css +6 -2
  38. data/guides/assets/stylesheets/print.css +1 -1
  39. data/guides/bug_report_templates/action_controller_gem.rb +47 -0
  40. data/guides/bug_report_templates/action_controller_master.rb +54 -0
  41. data/guides/bug_report_templates/active_record_gem.rb +5 -2
  42. data/guides/bug_report_templates/active_record_master.rb +3 -2
  43. data/guides/bug_report_templates/generic_gem.rb +15 -0
  44. data/guides/bug_report_templates/generic_master.rb +26 -0
  45. data/guides/rails_guides.rb +23 -4
  46. data/guides/rails_guides/generator.rb +1 -1
  47. data/guides/rails_guides/helpers.rb +4 -2
  48. data/guides/rails_guides/levenshtein.rb +27 -21
  49. data/guides/rails_guides/markdown.rb +11 -7
  50. data/guides/rails_guides/markdown/renderer.rb +1 -1
  51. data/guides/source/2_2_release_notes.md +3 -3
  52. data/guides/source/2_3_release_notes.md +12 -12
  53. data/guides/source/3_0_release_notes.md +10 -13
  54. data/guides/source/3_1_release_notes.md +7 -4
  55. data/guides/source/3_2_release_notes.md +17 -14
  56. data/guides/source/4_0_release_notes.md +110 -54
  57. data/guides/source/4_1_release_notes.md +730 -0
  58. data/guides/source/4_2_release_notes.md +877 -0
  59. data/guides/source/_license.html.erb +1 -1
  60. data/guides/source/_welcome.html.erb +6 -2
  61. data/guides/source/action_controller_overview.md +223 -57
  62. data/guides/source/action_mailer_basics.md +129 -76
  63. data/guides/source/action_view_overview.md +247 -246
  64. data/guides/source/active_job_basics.md +339 -0
  65. data/guides/source/active_model_basics.md +374 -20
  66. data/guides/source/active_record_basics.md +46 -45
  67. data/guides/source/active_record_callbacks.md +83 -28
  68. data/guides/source/{migrations.md → active_record_migrations.md} +191 -275
  69. data/guides/source/active_record_postgresql.md +433 -0
  70. data/guides/source/active_record_querying.md +382 -300
  71. data/guides/source/active_record_validations.md +64 -55
  72. data/guides/source/active_support_core_extensions.md +229 -187
  73. data/guides/source/active_support_instrumentation.md +23 -22
  74. data/guides/source/api_documentation_guidelines.md +167 -15
  75. data/guides/source/asset_pipeline.md +768 -294
  76. data/guides/source/association_basics.md +188 -96
  77. data/guides/source/autoloading_and_reloading_constants.md +1311 -0
  78. data/guides/source/caching_with_rails.md +45 -11
  79. data/guides/source/command_line.md +96 -65
  80. data/guides/source/configuring.md +404 -70
  81. data/guides/source/contributing_to_ruby_on_rails.md +270 -130
  82. data/guides/source/credits.html.erb +7 -3
  83. data/guides/source/debugging_rails_applications.md +471 -284
  84. data/guides/source/development_dependencies_install.md +115 -21
  85. data/guides/source/documents.yaml +31 -9
  86. data/guides/source/engines.md +737 -291
  87. data/guides/source/form_helpers.md +137 -89
  88. data/guides/source/generators.md +60 -28
  89. data/guides/source/getting_started.md +1007 -596
  90. data/guides/source/i18n.md +178 -96
  91. data/guides/source/index.html.erb +2 -1
  92. data/guides/source/initialization.md +248 -104
  93. data/guides/source/kindle/toc.html.erb +1 -1
  94. data/guides/source/layout.html.erb +14 -22
  95. data/guides/source/layouts_and_rendering.md +78 -46
  96. data/guides/source/maintenance_policy.md +78 -0
  97. data/guides/source/nested_model_forms.md +10 -7
  98. data/guides/source/plugins.md +66 -57
  99. data/guides/source/rails_application_templates.md +49 -12
  100. data/guides/source/rails_on_rack.md +50 -60
  101. data/guides/source/routing.md +190 -139
  102. data/guides/source/ruby_on_rails_guides_guidelines.md +12 -13
  103. data/guides/source/security.md +134 -83
  104. data/guides/source/testing.md +322 -200
  105. data/guides/source/upgrading_ruby_on_rails.md +834 -37
  106. data/guides/source/working_with_javascript_in_rails.md +36 -26
  107. data/guides/w3c_validator.rb +2 -0
  108. metadata +93 -116
  109. data/guides/assets/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
  110. data/guides/assets/images/getting_started/new_post.png +0 -0
  111. data/guides/assets/images/getting_started/post_with_comments.png +0 -0
  112. data/guides/assets/images/getting_started/show_action_for_posts.png +0 -0
  113. data/guides/assets/images/getting_started/template_is_missing_posts_new.png +0 -0
  114. data/guides/assets/images/getting_started/undefined_method_post_path.png +0 -0
  115. data/guides/assets/images/getting_started/unknown_action_create_for_posts.png +0 -0
  116. data/guides/assets/images/getting_started/unknown_action_new_for_posts.png +0 -0
  117. data/guides/assets/images/jaimeiniesta.jpg +0 -0
  118. data/guides/code/getting_started/Gemfile +0 -43
  119. data/guides/code/getting_started/Gemfile.lock +0 -150
  120. data/guides/code/getting_started/README.rdoc +0 -28
  121. data/guides/code/getting_started/Rakefile +0 -6
  122. data/guides/code/getting_started/app/assets/javascripts/application.js +0 -16
  123. data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
  124. data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
  125. data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +0 -3
  126. data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
  127. data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
  128. data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
  129. data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +0 -3
  130. data/guides/code/getting_started/app/controllers/application_controller.rb +0 -5
  131. data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -17
  132. data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -47
  133. data/guides/code/getting_started/app/controllers/welcome_controller.rb +0 -4
  134. data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
  135. data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
  136. data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -2
  137. data/guides/code/getting_started/app/helpers/welcome_helper.rb +0 -2
  138. data/guides/code/getting_started/app/models/comment.rb +0 -3
  139. data/guides/code/getting_started/app/models/post.rb +0 -7
  140. data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
  141. data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
  142. data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
  143. data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -27
  144. data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -5
  145. data/guides/code/getting_started/app/views/posts/index.html.erb +0 -21
  146. data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
  147. data/guides/code/getting_started/app/views/posts/show.html.erb +0 -18
  148. data/guides/code/getting_started/app/views/welcome/index.html.erb +0 -3
  149. data/guides/code/getting_started/bin/bundle +0 -4
  150. data/guides/code/getting_started/bin/rails +0 -4
  151. data/guides/code/getting_started/bin/rake +0 -4
  152. data/guides/code/getting_started/config.ru +0 -4
  153. data/guides/code/getting_started/config/application.rb +0 -18
  154. data/guides/code/getting_started/config/boot.rb +0 -4
  155. data/guides/code/getting_started/config/database.yml +0 -25
  156. data/guides/code/getting_started/config/environment.rb +0 -5
  157. data/guides/code/getting_started/config/environments/development.rb +0 -30
  158. data/guides/code/getting_started/config/environments/production.rb +0 -80
  159. data/guides/code/getting_started/config/environments/test.rb +0 -36
  160. data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
  161. data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +0 -4
  162. data/guides/code/getting_started/config/initializers/inflections.rb +0 -16
  163. data/guides/code/getting_started/config/initializers/locale.rb +0 -9
  164. data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
  165. data/guides/code/getting_started/config/initializers/secret_token.rb +0 -12
  166. data/guides/code/getting_started/config/initializers/session_store.rb +0 -3
  167. data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
  168. data/guides/code/getting_started/config/locales/en.yml +0 -23
  169. data/guides/code/getting_started/config/routes.rb +0 -7
  170. data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +0 -10
  171. data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +0 -11
  172. data/guides/code/getting_started/db/schema.rb +0 -33
  173. data/guides/code/getting_started/db/seeds.rb +0 -7
  174. data/guides/code/getting_started/public/404.html +0 -58
  175. data/guides/code/getting_started/public/422.html +0 -58
  176. data/guides/code/getting_started/public/500.html +0 -57
  177. data/guides/code/getting_started/public/favicon.ico +0 -0
  178. data/guides/code/getting_started/public/robots.txt +0 -5
  179. data/guides/code/getting_started/test/controllers/comments_controller_test.rb +0 -7
  180. data/guides/code/getting_started/test/controllers/posts_controller_test.rb +0 -7
  181. data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +0 -9
  182. data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
  183. data/guides/code/getting_started/test/fixtures/posts.yml +0 -9
  184. data/guides/code/getting_started/test/helpers/comments_helper_test.rb +0 -4
  185. data/guides/code/getting_started/test/helpers/posts_helper_test.rb +0 -4
  186. data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +0 -4
  187. data/guides/code/getting_started/test/models/comment_test.rb +0 -7
  188. data/guides/code/getting_started/test/models/post_test.rb +0 -7
  189. data/guides/code/getting_started/test/test_helper.rb +0 -15
  190. data/guides/source/kindle/KINDLE.md +0 -26
@@ -49,7 +49,9 @@ The `test_helper.rb` file holds the default configuration for your tests.
49
49
 
50
50
  ### The Low-Down on Fixtures
51
51
 
52
- For good tests, you'll need to give some thought to setting up test data. In Rails, you can handle this by defining and customizing fixtures.
52
+ For good tests, you'll need to give some thought to setting up test data.
53
+ In Rails, you can handle this by defining and customizing fixtures.
54
+ You can find comprehensive documentation in the [fixture api documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
53
55
 
54
56
  #### What Are Fixtures?
55
57
 
@@ -64,20 +66,42 @@ YAML-formatted fixtures are a very human-friendly way to describe your sample da
64
66
  Here's a sample YAML fixture file:
65
67
 
66
68
  ```yaml
67
- # lo & behold! I am a YAML comment!
69
+ # lo & behold! I am a YAML comment!
68
70
  david:
69
- name: David Heinemeier Hansson
70
- birthday: 1979-10-15
71
- profession: Systems development
71
+ name: David Heinemeier Hansson
72
+ birthday: 1979-10-15
73
+ profession: Systems development
72
74
 
73
75
  steve:
74
- name: Steve Ross Kellock
75
- birthday: 1974-09-27
76
- profession: guy with keyboard
76
+ name: Steve Ross Kellock
77
+ birthday: 1974-09-27
78
+ profession: guy with keyboard
77
79
  ```
78
80
 
79
81
  Each fixture is given a name followed by an indented list of colon-separated key/value pairs. Records are typically separated by a blank space. You can place comments in a fixture file by using the # character in the first column. Keys which resemble YAML keywords such as 'yes' and 'no' are quoted so that the YAML Parser correctly interprets them.
80
82
 
83
+ If you are working with [associations](/association_basics.html), you can simply
84
+ define a reference node between two different fixtures. Here's an example with
85
+ a `belongs_to`/`has_many` association:
86
+
87
+ ```yaml
88
+ # In fixtures/categories.yml
89
+ about:
90
+ name: About
91
+
92
+ # In fixtures/articles.yml
93
+ one:
94
+ title: Welcome to Rails!
95
+ body: Hello world!
96
+ category: about
97
+ ```
98
+
99
+ Note: For associations to reference one another by name, you cannot specify the `id:`
100
+ attribute on the fixtures. Rails will auto assign a primary key to be consistent between
101
+ runs. If you manually specify an `id:` attribute, this behavior will not work. For more
102
+ information on this association behavior please read the
103
+ [fixture api documentation](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html).
104
+
81
105
  #### ERB'in It Up
82
106
 
83
107
  ERB allows you to embed Ruby code within templates. The YAML fixture format is pre-processed with ERB when Rails loads fixtures. This allows you to use Ruby to help you generate some sample data. For example, the following code generates a thousand users:
@@ -92,7 +116,7 @@ user_<%= n %>:
92
116
 
93
117
  #### Fixtures in Action
94
118
 
95
- Rails by default automatically loads all fixtures from the `test/fixtures` folder for your unit and functional test. Loading involves three steps:
119
+ Rails by default automatically loads all fixtures from the `test/fixtures` folder for your models and controllers test. Loading involves three steps:
96
120
 
97
121
  * Remove any existing data from the table corresponding to the fixture
98
122
  * Load the fixture data into the table
@@ -116,29 +140,29 @@ email(david.girlfriend.email, david.location_tonight)
116
140
  Unit Testing your Models
117
141
  ------------------------
118
142
 
119
- In Rails, unit tests are what you write to test your models.
143
+ In Rails, models tests are what you write to test your models.
120
144
 
121
- For this guide we will be using Rails _scaffolding_. It will create the model, a migration, controller and views for the new resource in a single operation. It will also create a full test suite following Rails best practices. I will be using examples from this generated code and will be supplementing it with additional examples where necessary.
145
+ For this guide we will be using Rails _scaffolding_. It will create the model, a migration, controller and views for the new resource in a single operation. It will also create a full test suite following Rails best practices. We will be using examples from this generated code and will be supplementing it with additional examples where necessary.
122
146
 
123
- NOTE: For more information on Rails <i>scaffolding</i>, refer to [Getting Started with Rails](getting_started.html)
147
+ NOTE: For more information on Rails _scaffolding_, refer to [Getting Started with Rails](getting_started.html)
124
148
 
125
149
  When you use `rails generate scaffold`, for a resource among other things it creates a test stub in the `test/models` folder:
126
150
 
127
151
  ```bash
128
- $ rails generate scaffold post title:string body:text
152
+ $ bin/rails generate scaffold article title:string body:text
129
153
  ...
130
- create app/models/post.rb
131
- create test/models/post_test.rb
132
- create test/fixtures/posts.yml
154
+ create app/models/article.rb
155
+ create test/models/article_test.rb
156
+ create test/fixtures/articles.yml
133
157
  ...
134
158
  ```
135
159
 
136
- The default test stub in `test/models/post_test.rb` looks like this:
160
+ The default test stub in `test/models/article_test.rb` looks like this:
137
161
 
138
162
  ```ruby
139
163
  require 'test_helper'
140
164
 
141
- class PostTest < ActiveSupport::TestCase
165
+ class ArticleTest < ActiveSupport::TestCase
142
166
  # test "the truth" do
143
167
  # assert true
144
168
  # end
@@ -154,15 +178,15 @@ require 'test_helper'
154
178
  As you know by now, `test_helper.rb` specifies the default configuration to run our tests. This is included with all the tests, so any methods added to this file are available to all your tests.
155
179
 
156
180
  ```ruby
157
- class PostTest < ActiveSupport::TestCase
181
+ class ArticleTest < ActiveSupport::TestCase
158
182
  ```
159
183
 
160
- The `PostTest` class defines a _test case_ because it inherits from `ActiveSupport::TestCase`. `PostTest` thus has all the methods available from `ActiveSupport::TestCase`. You'll see those methods a little later in this guide.
184
+ The `ArticleTest` class defines a _test case_ because it inherits from `ActiveSupport::TestCase`. `ArticleTest` thus has all the methods available from `ActiveSupport::TestCase`. You'll see those methods a little later in this guide.
161
185
 
162
- Any method defined within a class inherited from `MiniTest::Unit::TestCase`
163
- (which is the superclass of `ActiveSupport::TestCase`) that begins with `test` (case sensitive) is simply called a test. So, `test_password`, `test_valid_password` and `testValidPassword` all are legal test names and are run automatically when the test case is run.
186
+ Any method defined within a class inherited from `Minitest::Test`
187
+ (which is the superclass of `ActiveSupport::TestCase`) that begins with `test_` (case sensitive) is simply called a test. So, `test_password` and `test_valid_password` are legal test names and are run automatically when the test case is run.
164
188
 
165
- Rails adds a `test` method that takes a test name and a block. It generates a normal `MiniTest::Unit` test with method names prefixed with `test_`. So,
189
+ Rails adds a `test` method that takes a test name and a block. It generates a normal `Minitest::Unit` test with method names prefixed with `test_`. So,
166
190
 
167
191
  ```ruby
168
192
  test "the truth" do
@@ -195,38 +219,25 @@ This line of code is called an _assertion_. An assertion is a line of code that
195
219
 
196
220
  Every test contains one or more assertions. Only when all the assertions are successful will the test pass.
197
221
 
198
- ### Preparing your Application for Testing
199
-
200
- Before you can run your tests, you need to ensure that the test database structure is current. For this you can use the following rake commands:
201
-
202
- ```bash
203
- $ rake db:migrate
204
- ...
205
- $ rake db:test:load
206
- ```
207
-
208
- The `rake db:migrate` above runs any pending migrations on the _development_ environment and updates `db/schema.rb`. The `rake db:test:load` recreates the test database from the current `db/schema.rb`. On subsequent attempts, it is a good idea to first run `db:test:prepare`, as it first checks for pending migrations and warns you appropriately.
209
-
210
- NOTE: `db:test:prepare` will fail with an error if `db/schema.rb` doesn't exist.
211
-
212
- #### Rake Tasks for Preparing your Application for Testing
222
+ ### Maintaining the test database schema
213
223
 
214
- | Tasks | Description |
215
- | ------------------------------ | ------------------------------------------------------------------------- |
216
- | `rake db:test:clone` | Recreate the test database from the current environment's database schema |
217
- | `rake db:test:clone_structure` | Recreate the test database from the development structure |
218
- | `rake db:test:load` | Recreate the test database from the current `schema.rb` |
219
- | `rake db:test:prepare` | Check for pending migrations and load the test schema |
220
- | `rake db:test:purge` | Empty the test database. |
224
+ In order to run your tests, your test database will need to have the current
225
+ structure. The test helper checks whether your test database has any pending
226
+ migrations. If so, it will try to load your `db/schema.rb` or `db/structure.sql`
227
+ into the test database. If migrations are still pending, an error will be
228
+ raised. Usually this indicates that your schema is not fully migrated. Running
229
+ the migrations against the development database (`bin/rake db:migrate`) will
230
+ bring the schema up to date.
221
231
 
222
- TIP: You can see all these rake tasks and their descriptions by running `rake --tasks --describe`
232
+ NOTE: If existing migrations required modifications, the test database needs to
233
+ be rebuilt. This can be done by executing `bin/rake db:test:prepare`.
223
234
 
224
235
  ### Running Tests
225
236
 
226
237
  Running a test is as simple as invoking the file containing the test cases through `rake test` command.
227
238
 
228
239
  ```bash
229
- $ rake test test/models/post_test.rb
240
+ $ bin/rake test test/models/article_test.rb
230
241
  .
231
242
 
232
243
  Finished tests in 0.009262s, 107.9680 tests/s, 107.9680 assertions/s.
@@ -237,7 +248,7 @@ Finished tests in 0.009262s, 107.9680 tests/s, 107.9680 assertions/s.
237
248
  You can also run a particular test method from the test case by running the test and providing the `test method name`.
238
249
 
239
250
  ```bash
240
- $ rake test test/models/post_test.rb test_the_truth
251
+ $ bin/rake test test/models/article_test.rb test_the_truth
241
252
  .
242
253
 
243
254
  Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
@@ -249,25 +260,25 @@ This will run all test methods from the test case. Note that `test_helper.rb` is
249
260
 
250
261
  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.
251
262
 
252
- To see how a test failure is reported, you can add a failing test to the `post_test.rb` test case.
263
+ To see how a test failure is reported, you can add a failing test to the `article_test.rb` test case.
253
264
 
254
265
  ```ruby
255
- test "should not save post without title" do
256
- post = Post.new
257
- assert !post.save
266
+ test "should not save article without title" do
267
+ article = Article.new
268
+ assert_not article.save
258
269
  end
259
270
  ```
260
271
 
261
272
  Let us run this newly added test.
262
273
 
263
274
  ```bash
264
- $ rake test test/models/post_test.rb test_should_not_save_post_without_title
275
+ $ bin/rake test test/models/article_test.rb test_should_not_save_article_without_title
265
276
  F
266
277
 
267
278
  Finished tests in 0.044632s, 22.4054 tests/s, 22.4054 assertions/s.
268
279
 
269
280
  1) Failure:
270
- test_should_not_save_post_without_title(PostTest) [test/models/post_test.rb:6]:
281
+ test_should_not_save_article_without_title(ArticleTest) [test/models/article_test.rb:6]:
271
282
  Failed assertion, no message given.
272
283
 
273
284
  1 tests, 1 assertions, 1 failures, 0 errors, 0 skips
@@ -276,9 +287,9 @@ Failed assertion, no message given.
276
287
  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:
277
288
 
278
289
  ```ruby
279
- test "should not save post without title" do
280
- post = Post.new
281
- assert !post.save, "Saved the post without a title"
290
+ test "should not save article without title" do
291
+ article = Article.new
292
+ assert_not article.save, "Saved the article without a title"
282
293
  end
283
294
  ```
284
295
 
@@ -286,14 +297,14 @@ Running this test shows the friendlier assertion message:
286
297
 
287
298
  ```bash
288
299
  1) Failure:
289
- test_should_not_save_post_without_title(PostTest) [test/models/post_test.rb:6]:
290
- Saved the post without a title
300
+ test_should_not_save_article_without_title(ArticleTest) [test/models/article_test.rb:6]:
301
+ Saved the article without a title
291
302
  ```
292
303
 
293
304
  Now to get this test to pass we can add a model level validation for the _title_ field.
294
305
 
295
306
  ```ruby
296
- class Post < ActiveRecord::Base
307
+ class Article < ActiveRecord::Base
297
308
  validates :title, presence: true
298
309
  end
299
310
  ```
@@ -301,7 +312,7 @@ end
301
312
  Now the test should pass. Let us verify by running the test again:
302
313
 
303
314
  ```bash
304
- $ rake test test/models/post_test.rb test_should_not_save_post_without_title
315
+ $ bin/rake test test/models/article_test.rb test_should_not_save_article_without_title
305
316
  .
306
317
 
307
318
  Finished tests in 0.047721s, 20.9551 tests/s, 20.9551 assertions/s.
@@ -326,15 +337,15 @@ end
326
337
  Now you can see even more output in the console from running the tests:
327
338
 
328
339
  ```bash
329
- $ rake test test/models/post_test.rb test_should_report_error
340
+ $ bin/rake test test/models/article_test.rb test_should_report_error
330
341
  E
331
342
 
332
343
  Finished tests in 0.030974s, 32.2851 tests/s, 0.0000 assertions/s.
333
344
 
334
345
  1) Error:
335
- test_should_report_error(PostTest):
336
- NameError: undefined local variable or method `some_undefined_variable' for #<PostTest:0x007fe32e24afe0>
337
- test/models/post_test.rb:10:in `block in <class:PostTest>'
346
+ test_should_report_error(ArticleTest):
347
+ NameError: undefined local variable or method `some_undefined_variable' for #<ArticleTest:0x007fe32e24afe0>
348
+ test/models/article_test.rb:10:in `block in <class:ArticleTest>'
338
349
 
339
350
  1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
340
351
  ```
@@ -343,6 +354,17 @@ Notice the 'E' in the output. It denotes a test with error.
343
354
 
344
355
  NOTE: The execution of each test method stops as soon as any error or an assertion failure is encountered, and the test suite continues with the next method. All test methods are executed in alphabetical order.
345
356
 
357
+ When a test fails you are presented with the corresponding backtrace. By default
358
+ Rails filters that backtrace and will only print lines relevant to your
359
+ application. This eliminates the framework noise and helps to focus on your
360
+ code. However there are situations when you want to see the full
361
+ backtrace. simply set the `BACKTRACE` environment variable to enable this
362
+ behavior:
363
+
364
+ ```bash
365
+ $ BACKTRACE=1 bin/rake test test/models/article_test.rb
366
+ ```
367
+
346
368
  ### What to Include in Your Unit Tests
347
369
 
348
370
  Ideally, you would like to include a test for everything which could possibly break. It's a good practice to have at least one test for each of your validations and at least one test for every method in your model.
@@ -352,43 +374,51 @@ Ideally, you would like to include a test for everything which could possibly br
352
374
  By now you've caught a glimpse of some of the assertions that are available. Assertions are the worker bees of testing. They are the ones that actually perform the checks to ensure that things are going as planned.
353
375
 
354
376
  There are a bunch of different types of assertions you can use.
355
- Here's an extract of the assertions you can use with `minitest`, the default testing library used by Rails. The `[msg]` parameter is an optional string message you can specify to make your test failure messages clearer. It's not required.
377
+ Here's an extract of the assertions you can use with [`Minitest`](https://github.com/seattlerb/minitest), the default testing library used by Rails. The `[msg]` parameter is an optional string message you can specify to make your test failure messages clearer. It's not required.
356
378
 
357
379
  | Assertion | Purpose |
358
380
  | ---------------------------------------------------------------- | ------- |
359
381
  | `assert( test, [msg] )` | Ensures that `test` is true.|
360
- | `refute( test, [msg] )` | Ensures that `test` is false.|
382
+ | `assert_not( test, [msg] )` | Ensures that `test` is false.|
361
383
  | `assert_equal( expected, actual, [msg] )` | Ensures that `expected == actual` is true.|
362
- | `refute_equal( expected, actual, [msg] )` | Ensures that `expected != actual` is true.|
384
+ | `assert_not_equal( expected, actual, [msg] )` | Ensures that `expected != actual` is true.|
363
385
  | `assert_same( expected, actual, [msg] )` | Ensures that `expected.equal?(actual)` is true.|
364
- | `refute_same( expected, actual, [msg] )` | Ensures that `expected.equal?(actual)` is false.|
386
+ | `assert_not_same( expected, actual, [msg] )` | Ensures that `expected.equal?(actual)` is false.|
365
387
  | `assert_nil( obj, [msg] )` | Ensures that `obj.nil?` is true.|
366
- | `refute_nil( obj, [msg] )` | Ensures that `obj.nil?` is false.|
388
+ | `assert_not_nil( obj, [msg] )` | Ensures that `obj.nil?` is false.|
389
+ | `assert_empty( obj, [msg] )` | Ensures that `obj` is `empty?`.|
390
+ | `assert_not_empty( obj, [msg] )` | Ensures that `obj` is not `empty?`.|
367
391
  | `assert_match( regexp, string, [msg] )` | Ensures that a string matches the regular expression.|
368
- | `refute_match( regexp, string, [msg] )` | Ensures that a string doesn't match the regular expression.|
392
+ | `assert_no_match( regexp, string, [msg] )` | Ensures that a string doesn't match the regular expression.|
393
+ | `assert_includes( collection, obj, [msg] )` | Ensures that `obj` is in `collection`.|
394
+ | `assert_not_includes( collection, obj, [msg] )` | Ensures that `obj` is not in `collection`.|
369
395
  | `assert_in_delta( expecting, actual, [delta], [msg] )` | Ensures that the numbers `expected` and `actual` are within `delta` of each other.|
370
- | `refute_in_delta( expecting, actual, [delta], [msg] )` | Ensures that the numbers `expected` and `actual` are not within `delta` of each other.|
396
+ | `assert_not_in_delta( expecting, actual, [delta], [msg] )` | Ensures that the numbers `expected` and `actual` are not within `delta` of each other.|
371
397
  | `assert_throws( symbol, [msg] ) { block }` | Ensures that the given block throws the symbol.|
372
398
  | `assert_raises( exception1, exception2, ... ) { block }` | Ensures that the given block raises one of the given exceptions.|
373
399
  | `assert_nothing_raised( exception1, exception2, ... ) { block }` | Ensures that the given block doesn't raise one of the given exceptions.|
374
400
  | `assert_instance_of( class, obj, [msg] )` | Ensures that `obj` is an instance of `class`.|
375
- | `refute_instance_of( class, obj, [msg] )` | Ensures that `obj` is not an instance of `class`.|
401
+ | `assert_not_instance_of( class, obj, [msg] )` | Ensures that `obj` is not an instance of `class`.|
376
402
  | `assert_kind_of( class, obj, [msg] )` | Ensures that `obj` is or descends from `class`.|
377
- | `refute_kind_of( class, obj, [msg] )` | Ensures that `obj` is not an instance of `class` and is not descending from it.|
403
+ | `assert_not_kind_of( class, obj, [msg] )` | Ensures that `obj` is not an instance of `class` and is not descending from it.|
378
404
  | `assert_respond_to( obj, symbol, [msg] )` | Ensures that `obj` responds to `symbol`.|
379
- | `refute_respond_to( obj, symbol, [msg] )` | Ensures that `obj` does not respond to `symbol`.|
405
+ | `assert_not_respond_to( obj, symbol, [msg] )` | Ensures that `obj` does not respond to `symbol`.|
380
406
  | `assert_operator( obj1, operator, [obj2], [msg] )` | Ensures that `obj1.operator(obj2)` is true.|
381
- | `refute_operator( obj1, operator, [obj2], [msg] )` | Ensures that `obj1.operator(obj2)` is false.|
407
+ | `assert_not_operator( obj1, operator, [obj2], [msg] )` | Ensures that `obj1.operator(obj2)` is false.|
408
+ | `assert_predicate ( obj, predicate, [msg] )` | Ensures that `obj.predicate` is true, e.g. `assert_predicate str, :empty?`|
409
+ | `assert_not_predicate ( obj, predicate, [msg] )` | Ensures that `obj.predicate` is false, e.g. `assert_not_predicate str, :empty?`|
382
410
  | `assert_send( array, [msg] )` | Ensures that executing the method listed in `array[1]` on the object in `array[0]` with the parameters of `array[2 and up]` is true. This one is weird eh?|
383
411
  | `flunk( [msg] )` | Ensures failure. This is useful to explicitly mark a test that isn't finished yet.|
384
412
 
413
+ The above are subset of assertions that minitest supports. For an exhaustive & more up-to-date list, please check [Minitest API documentation](http://docs.seattlerb.org/minitest/), specifically [`Minitest::Assertions`](http://docs.seattlerb.org/minitest/Minitest/Assertions.html)
414
+
385
415
  Because of the modular nature of the testing framework, it is possible to create your own assertions. In fact, that's exactly what Rails does. It includes some specialized assertions to make your life easier.
386
416
 
387
417
  NOTE: Creating your own assertions is an advanced topic that we won't cover in this tutorial.
388
418
 
389
419
  ### Rails Specific Assertions
390
420
 
391
- Rails adds some custom assertions of its own to the `test/unit` framework:
421
+ Rails adds some custom assertions of its own to the `minitest` framework:
392
422
 
393
423
  | Assertion | Purpose |
394
424
  | --------------------------------------------------------------------------------- | ------- |
@@ -396,8 +426,8 @@ Rails adds some custom assertions of its own to the `test/unit` framework:
396
426
  | `assert_no_difference(expressions, message = nil, &amp;block)` | Asserts that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.|
397
427
  | `assert_recognizes(expected_options, path, extras={}, message=nil)` | Asserts that the routing of the given path was handled correctly and that the parsed options (given in the expected_options hash) match path. Basically, it asserts that Rails recognizes the route given by expected_options.|
398
428
  | `assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)` | Asserts that the provided options can be used to generate the provided path. This is the inverse of assert_recognizes. The extras parameter is used to tell the request the names and values of additional request parameters that would be in a query string. The message parameter allows you to specify a custom error message for assertion failures.|
399
- | `assert_response(type, message = nil)` | Asserts that the response comes with a specific status code. You can specify `:success` to indicate 200-299, `:redirect` to indicate 300-399, `:missing` to indicate 404, or `:error` to match the 500-599 range|
400
- | `assert_redirected_to(options = {}, message=nil)` | Assert that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that `assert_redirected_to(controller: "weblog")` will also match the redirection of `redirect_to(controller: "weblog", action: "show")` and so on.|
429
+ | `assert_response(type, message = nil)` | Asserts that the response comes with a specific status code. You can specify `:success` to indicate 200-299, `:redirect` to indicate 300-399, `:missing` to indicate 404, or `:error` to match the 500-599 range. You can also pass an explicit status number or its symbolic equivalent. For more information, see [full list of status codes](http://rubydoc.info/github/rack/rack/master/Rack/Utils#HTTP_STATUS_CODES-constant) and how their [mapping](http://rubydoc.info/github/rack/rack/master/Rack/Utils#SYMBOL_TO_STATUS_CODE-constant) works.|
430
+ | `assert_redirected_to(options = {}, message=nil)` | Assert that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that `assert_redirected_to(controller: "weblog")` will also match the redirection of `redirect_to(controller: "weblog", action: "show")` and so on. You can also pass named routes such as `assert_redirected_to root_path` and Active Record objects such as `assert_redirected_to @article`.|
401
431
  | `assert_template(expected = nil, message=nil)` | Asserts that the request was rendered with the appropriate template file.|
402
432
 
403
433
  You'll see the usage of some of these assertions in the next chapter.
@@ -417,24 +447,26 @@ You should test for things such as:
417
447
  * was the correct object stored in the response template?
418
448
  * was the appropriate message displayed to the user in the view?
419
449
 
420
- Now that we have used Rails scaffold generator for our `Post` resource, it has already created the controller code and tests. You can take look at the file `posts_controller_test.rb` in the `test/controllers` directory.
450
+ Now that we have used Rails scaffold generator for our `Article` resource, it has already created the controller code and tests. You can take look at the file `articles_controller_test.rb` in the `test/controllers` directory.
421
451
 
422
- Let me take you through one such test, `test_should_get_index` from the file `posts_controller_test.rb`.
452
+ Let me take you through one such test, `test_should_get_index` from the file `articles_controller_test.rb`.
423
453
 
424
454
  ```ruby
425
- test "should get index" do
426
- get :index
427
- assert_response :success
428
- assert_not_nil assigns(:posts)
455
+ class ArticlesControllerTest < ActionController::TestCase
456
+ test "should get index" do
457
+ get :index
458
+ assert_response :success
459
+ assert_not_nil assigns(:articles)
460
+ end
429
461
  end
430
462
  ```
431
463
 
432
- In the `test_should_get_index` test, Rails simulates a request on the action called `index`, making sure the request was successful and also ensuring that it assigns a valid `posts` instance variable.
464
+ In the `test_should_get_index` test, Rails simulates a request on the action called `index`, making sure the request was successful and also ensuring that it assigns a valid `articles` instance variable.
433
465
 
434
466
  The `get` method kicks off the web request and populates the results into the response. It accepts 4 arguments:
435
467
 
436
468
  * The action of the controller you are requesting. This can be in the form of a string or a symbol.
437
- * An optional hash of request parameters to pass into the action (eg. query string parameters or post variables).
469
+ * An optional hash of request parameters to pass into the action (eg. query string parameters or article variables).
438
470
  * An optional hash of session variables to pass along with the request.
439
471
  * An optional hash of flash values.
440
472
 
@@ -450,17 +482,17 @@ Another example: Calling the `:view` action, passing an `id` of 12 as the `param
450
482
  get(:view, {'id' => '12'}, nil, {'message' => 'booya!'})
451
483
  ```
452
484
 
453
- NOTE: If you try running `test_should_create_post` test from `posts_controller_test.rb` it will fail on account of the newly added model level validation and rightly so.
485
+ NOTE: If you try running `test_should_create_article` test from `articles_controller_test.rb` it will fail on account of the newly added model level validation and rightly so.
454
486
 
455
- Let us modify `test_should_create_post` test in `posts_controller_test.rb` so that all our test pass:
487
+ Let us modify `test_should_create_article` test in `articles_controller_test.rb` so that all our test pass:
456
488
 
457
489
  ```ruby
458
- test "should create post" do
459
- assert_difference('Post.count') do
460
- post :create, post: {title: 'Some title'}
490
+ test "should create article" do
491
+ assert_difference('Article.count') do
492
+ post :create, article: {title: 'Some title'}
461
493
  end
462
494
 
463
- assert_redirected_to post_path(assigns(:post))
495
+ assert_redirected_to article_path(assigns(:article))
464
496
  end
465
497
  ```
466
498
 
@@ -511,12 +543,14 @@ You also have access to three instance variables in your functional tests:
511
543
 
512
544
  ### Setting Headers and CGI variables
513
545
 
514
- Headers and cgi variables can be set directly on the `@request`
515
- instance variable:
546
+ [HTTP headers](http://tools.ietf.org/search/rfc2616#section-5.3)
547
+ and
548
+ [CGI variables](http://tools.ietf.org/search/rfc3875#section-4.1)
549
+ can be set directly on the `@request` instance variable:
516
550
 
517
551
  ```ruby
518
552
  # setting a HTTP Header
519
- @request.headers["Accepts"] = "text/plain, text/html"
553
+ @request.headers["Accept"] = "text/plain, text/html"
520
554
  get :index # simulate the request with custom header
521
555
 
522
556
  # setting a CGI variable
@@ -567,12 +601,12 @@ is the correct way to assert for the layout when the view renders a partial with
567
601
  Here's another example that uses `flash`, `assert_redirected_to`, and `assert_difference`:
568
602
 
569
603
  ```ruby
570
- test "should create post" do
571
- assert_difference('Post.count') do
572
- post :create, post: {title: 'Hi', body: 'This is my first post.'}
604
+ test "should create article" do
605
+ assert_difference('Article.count') do
606
+ post :create, article: {title: 'Hi', body: 'This is my first article.'}
573
607
  end
574
- assert_redirected_to post_path(assigns(:post))
575
- assert_equal 'Post was successfully created.', flash[:notice]
608
+ assert_redirected_to article_path(assigns(:article))
609
+ assert_equal 'Article was successfully created.', flash[:notice]
576
610
  end
577
611
  ```
578
612
 
@@ -580,13 +614,13 @@ end
580
614
 
581
615
  Testing the response to your request by asserting the presence of key HTML elements and their content is a useful way to test the views of your application. The `assert_select` assertion allows you to do this by using a simple yet powerful syntax.
582
616
 
583
- NOTE: You may find references to `assert_tag` in other documentation, but this is now deprecated in favor of `assert_select`.
617
+ NOTE: You may find references to `assert_tag` in other documentation. This has been removed in 4.2. Use `assert_select` instead.
584
618
 
585
619
  There are two forms of `assert_select`:
586
620
 
587
- `assert_select(selector, [equality], [message])` ensures that the equality condition is met on the selected elements through the selector. The selector may be a CSS selector expression (String), an expression with substitution values, or an `HTML::Selector` object.
621
+ `assert_select(selector, [equality], [message])` ensures that the equality condition is met on the selected elements through the selector. The selector may be a CSS selector expression (String) or an expression with substitution values.
588
622
 
589
- `assert_select(element, selector, [equality], [message])` ensures that the equality condition is met on all the selected elements through the selector starting from the _element_ (instance of `HTML::Node`) and its descendants.
623
+ `assert_select(element, selector, [equality], [message])` ensures that the equality condition is met on all the selected elements through the selector starting from the _element_ (instance of `Nokogiri::XML::Node` or `Nokogiri::XML::NodeSet`) and its descendants.
590
624
 
591
625
  For example, you could verify the contents on the title element in your response with:
592
626
 
@@ -616,17 +650,17 @@ assert_select "ol" do
616
650
  end
617
651
  ```
618
652
 
619
- The `assert_select` assertion is quite powerful. For more advanced usage, refer to its [documentation](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/SelectorAssertions.html).
653
+ The `assert_select` assertion is quite powerful. For more advanced usage, refer to its [documentation](https://github.com/rails/rails-dom-testing/blob/master/lib/rails/dom/testing/assertions/selector_assertions.rb).
620
654
 
621
655
  #### Additional View-Based Assertions
622
656
 
623
657
  There are more assertions that are primarily used in testing views:
624
658
 
625
- | Assertion | Purpose |
626
- | ---------------------------------------------------------- | ------- |
627
- | `assert_select_email` | Allows you to make assertions on the body of an e-mail. |
628
- | `assert_select_encoded` | Allows you to make assertions on encoded HTML. It does this by un-encoding the contents of each element and then calling the block with all the un-encoded elements.|
629
- | `css_select(selector)` or `css_select(element, selector)` | Returns an array of all the elements selected by the _selector_. In the second variant it first matches the base _element_ and tries to match the _selector_ expression on any of its children. If there are no matches both variants return an empty array.|
659
+ | Assertion | Purpose |
660
+ | --------------------------------------------------------- | ------- |
661
+ | `assert_select_email` | Allows you to make assertions on the body of an e-mail. |
662
+ | `assert_select_encoded` | Allows you to make assertions on encoded HTML. It does this by un-encoding the contents of each element and then calling the block with all the un-encoded elements.|
663
+ | `css_select(selector)` or `css_select(element, selector)` | Returns an array of all the elements selected by the _selector_. In the second variant it first matches the base _element_ and tries to match the _selector_ expression on any of its children. If there are no matches both variants return an empty array.|
630
664
 
631
665
  Here's an example of using `assert_select_email`:
632
666
 
@@ -644,7 +678,7 @@ Integration tests are used to test the interaction among any number of controlle
644
678
  Unlike Unit and Functional tests, integration tests have to be explicitly created under the 'test/integration' folder within your application. Rails provides a generator to create an integration test skeleton for you.
645
679
 
646
680
  ```bash
647
- $ rails generate integration_test user_flows
681
+ $ bin/rails generate integration_test user_flows
648
682
  exists test/integration/
649
683
  create test/integration/user_flows_test.rb
650
684
  ```
@@ -690,8 +724,6 @@ A simple integration test that exercises multiple controllers:
690
724
  require 'test_helper'
691
725
 
692
726
  class UserFlowsTest < ActionDispatch::IntegrationTest
693
- fixtures :users
694
-
695
727
  test "login and browse site" do
696
728
  # login via https
697
729
  https!
@@ -703,9 +735,9 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
703
735
  assert_equal 'Welcome david!', flash[:notice]
704
736
 
705
737
  https!(false)
706
- get "/posts/all"
738
+ get "/articles/all"
707
739
  assert_response :success
708
- assert assigns(:products)
740
+ assert assigns(:articles)
709
741
  end
710
742
  end
711
743
  ```
@@ -718,10 +750,7 @@ Here's an example of multiple sessions and custom DSL in an integration test
718
750
  require 'test_helper'
719
751
 
720
752
  class UserFlowsTest < ActionDispatch::IntegrationTest
721
- fixtures :users
722
-
723
753
  test "login and browse site" do
724
-
725
754
  # User david logs in
726
755
  david = login(:david)
727
756
  # User guest logs in
@@ -741,102 +770,95 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
741
770
 
742
771
  private
743
772
 
744
- module CustomDsl
745
- def browses_site
746
- get "/products/all"
747
- assert_response :success
748
- assert assigns(:products)
773
+ module CustomDsl
774
+ def browses_site
775
+ get "/products/all"
776
+ assert_response :success
777
+ assert assigns(:products)
778
+ end
749
779
  end
750
- end
751
780
 
752
- def login(user)
753
- open_session do |sess|
754
- sess.extend(CustomDsl)
755
- u = users(user)
756
- sess.https!
757
- sess.post "/login", username: u.username, password: u.password
758
- assert_equal '/welcome', path
759
- sess.https!(false)
781
+ def login(user)
782
+ open_session do |sess|
783
+ sess.extend(CustomDsl)
784
+ u = users(user)
785
+ sess.https!
786
+ sess.post "/login", username: u.username, password: u.password
787
+ assert_equal '/welcome', sess.path
788
+ sess.https!(false)
789
+ end
760
790
  end
761
- end
762
791
  end
763
792
  ```
764
793
 
765
794
  Rake Tasks for Running your Tests
766
795
  ---------------------------------
767
796
 
768
- 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.
769
-
770
- | Tasks | Description |
771
- | ------------------------ | ----------- |
772
- | `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake test` as Rails will run all the tests by default|
773
- | `rake test:controllers` | Runs all the controller tests from `test/controllers`|
774
- | `rake test:functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional`|
775
- | `rake test:helpers` | Runs all the helper tests from `test/helpers`|
776
- | `rake test:integration` | Runs all the integration tests from `test/integration`|
777
- | `rake test:mailers` | Runs all the mailer tests from `test/mailers`|
778
- | `rake test:models` | Runs all the model tests from `test/models`|
779
- | `rake test:units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit`|
780
-
781
- There're also some test commands which you can initiate by running rake tasks:
782
-
783
- | Tasks | Description |
784
- | ------------------------ | ----------- |
785
- | `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake` as the _test_ target is the default.|
786
- | `rake test:recent` | Tests recent changes|
787
- | `rake test:uncommitted` | Runs all the tests which are uncommitted. Supports Subversion and Git|
788
-
789
- Brief Note About `MiniTest`
797
+ Rails comes with a number of built-in rake tasks to help with testing. The
798
+ table below lists the commands included in the default Rakefile when a Rails
799
+ project is created.
800
+
801
+ | Tasks | Description |
802
+ | ----------------------- | ----------- |
803
+ | `rake test` | Runs all tests in the `test` folder. You can also simply run `rake` as Rails will run all the tests by default |
804
+ | `rake test:controllers` | Runs all the controller tests from `test/controllers` |
805
+ | `rake test:functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional` |
806
+ | `rake test:helpers` | Runs all the helper tests from `test/helpers` |
807
+ | `rake test:integration` | Runs all the integration tests from `test/integration` |
808
+ | `rake test:jobs` | Runs all the job tests from `test/jobs` |
809
+ | `rake test:mailers` | Runs all the mailer tests from `test/mailers` |
810
+ | `rake test:models` | Runs all the model tests from `test/models` |
811
+ | `rake test:units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit` |
812
+ | `rake test:db` | Runs all tests in the `test` folder and resets the db |
813
+
814
+
815
+ A Brief Note About Minitest
790
816
  -----------------------------
791
817
 
792
- 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
793
- us to use all of the basic assertions in our tests.
818
+ Ruby ships with a vast Standard Library for all common use-cases including testing. Since version 1.9, Ruby provides `Minitest`, a framework for testing. All the basic assertions such as `assert_equal` discussed above are actually defined in `Minitest::Assertions`. The classes `ActiveSupport::TestCase`, `ActionController::TestCase`, `ActionMailer::TestCase`, `ActionView::TestCase` and `ActionDispatch::IntegrationTest` - which we have been inheriting in our test classes - include `Minitest::Assertions`, allowing us to use all of the basic assertions in our tests.
794
819
 
795
- Ruby 1.9 introduced `MiniTest`, an updated version of `Test::Unit` which provides a backwards compatible API for `Test::Unit`. You could also use `MiniTest` in Ruby 1.8 by installing the `minitest` gem.
796
-
797
- NOTE: For more information on `Test::Unit`, refer to [test/unit Documentation](http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/)
798
- For more information on `MiniTest`, refer to [Minitest](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/minitest/unit/rdoc/)
820
+ NOTE: For more information on `Minitest`, refer to [Minitest](http://ruby-doc.org/stdlib-2.1.0/libdoc/minitest/rdoc/MiniTest.html)
799
821
 
800
822
  Setup and Teardown
801
823
  ------------------
802
824
 
803
- If you would like to run a block of code before the start of each test and another block of code after the end of each test you have two special callbacks for your rescue. Let's take note of this by looking at an example for our functional test in `Posts` controller:
825
+ If you would like to run a block of code before the start of each test and another block of code after the end of each test you have two special callbacks for your rescue. Let's take note of this by looking at an example for our functional test in `Articles` controller:
804
826
 
805
827
  ```ruby
806
828
  require 'test_helper'
807
829
 
808
- class PostsControllerTest < ActionController::TestCase
830
+ class ArticlesControllerTest < ActionController::TestCase
809
831
 
810
832
  # called before every single test
811
833
  def setup
812
- @post = posts(:one)
834
+ @article = articles(:one)
813
835
  end
814
836
 
815
837
  # called after every single test
816
838
  def teardown
817
- # as we are re-initializing @post before every test
839
+ # as we are re-initializing @article before every test
818
840
  # setting it to nil here is not essential but I hope
819
841
  # you understand how you can use the teardown method
820
- @post = nil
842
+ @article = nil
821
843
  end
822
844
 
823
- test "should show post" do
824
- get :show, id: @post.id
845
+ test "should show article" do
846
+ get :show, id: @article.id
825
847
  assert_response :success
826
848
  end
827
849
 
828
- test "should destroy post" do
829
- assert_difference('Post.count', -1) do
830
- delete :destroy, id: @post.id
850
+ test "should destroy article" do
851
+ assert_difference('Article.count', -1) do
852
+ delete :destroy, id: @article.id
831
853
  end
832
854
 
833
- assert_redirected_to posts_path
855
+ assert_redirected_to articles_path
834
856
  end
835
857
 
836
858
  end
837
859
  ```
838
860
 
839
- Above, the `setup` method is called before each test and so `@post` is available for each of the tests. Rails implements `setup` and `teardown` as `ActiveSupport::Callbacks`. Which essentially means you need not only use `setup` and `teardown` as methods in your tests. You could specify them by using:
861
+ Above, the `setup` method is called before each test and so `@article` is available for each of the tests. Rails implements `setup` and `teardown` as `ActiveSupport::Callbacks`. Which essentially means you need not only use `setup` and `teardown` as methods in your tests. You could specify them by using:
840
862
 
841
863
  * a block
842
864
  * a method (like in the earlier example)
@@ -848,51 +870,56 @@ Let's see the earlier example by specifying `setup` callback by specifying a met
848
870
  ```ruby
849
871
  require 'test_helper'
850
872
 
851
- class PostsControllerTest < ActionController::TestCase
873
+ class ArticlesControllerTest < ActionController::TestCase
852
874
 
853
875
  # called before every single test
854
- setup :initialize_post
876
+ setup :initialize_article
855
877
 
856
878
  # called after every single test
857
879
  def teardown
858
- @post = nil
880
+ @article = nil
859
881
  end
860
882
 
861
- test "should show post" do
862
- get :show, id: @post.id
883
+ test "should show article" do
884
+ get :show, id: @article.id
863
885
  assert_response :success
864
886
  end
865
887
 
866
- test "should update post" do
867
- patch :update, id: @post.id, post: {}
868
- assert_redirected_to post_path(assigns(:post))
888
+ test "should update article" do
889
+ patch :update, id: @article.id, article: {}
890
+ assert_redirected_to article_path(assigns(:article))
869
891
  end
870
892
 
871
- test "should destroy post" do
872
- assert_difference('Post.count', -1) do
873
- delete :destroy, id: @post.id
893
+ test "should destroy article" do
894
+ assert_difference('Article.count', -1) do
895
+ delete :destroy, id: @article.id
874
896
  end
875
897
 
876
- assert_redirected_to posts_path
898
+ assert_redirected_to articles_path
877
899
  end
878
900
 
879
901
  private
880
902
 
881
- def initialize_post
882
- @post = posts(:one)
883
- end
884
-
903
+ def initialize_article
904
+ @article = articles(:one)
905
+ end
885
906
  end
886
907
  ```
887
908
 
888
909
  Testing Routes
889
910
  --------------
890
911
 
891
- Like everything else in your Rails application, it is recommended that you test your routes. An example test for a route in the default `show` action of `Posts` controller above should look like:
912
+ Like everything else in your Rails application, it is recommended that you test your routes. Below are example tests for the routes of default `show` and `create` action of `Articles` controller above and it should look like:
892
913
 
893
914
  ```ruby
894
- test "should route to post" do
895
- assert_routing '/posts/1', {controller: "posts", action: "show", id: "1"}
915
+ class ArticleRoutesTest < ActionController::TestCase
916
+ test "should route to article" do
917
+ assert_routing '/articles/1', { controller: "articles", action: "show", id: "1" }
918
+ end
919
+
920
+ test "should route to create article" do
921
+ assert_routing({ method: 'post', path: '/articles' }, { controller: "articles", action: "create" })
922
+ end
896
923
  end
897
924
  ```
898
925
 
@@ -903,7 +930,7 @@ Testing mailer classes requires some specific tools to do a thorough job.
903
930
 
904
931
  ### Keeping the Postman in Check
905
932
 
906
- Your mailer classes like every other part of your Rails application should be tested to ensure that it is working as expected.
933
+ Your mailer classes - like every other part of your Rails application - should be tested to ensure that it is working as expected.
907
934
 
908
935
  The goals of testing your mailer classes are to ensure that:
909
936
 
@@ -923,7 +950,7 @@ In order to test that your mailer is working as expected, you can use unit tests
923
950
 
924
951
  For the purposes of unit testing a mailer, fixtures are used to provide an example of how the output _should_ look. Because these are example emails, and not Active Record data like the other fixtures, they are kept in their own subdirectory apart from the other fixtures. The name of the directory within `test/fixtures` directly corresponds to the name of the mailer. So, for a mailer named `UserMailer`, the fixtures should reside in `test/fixtures/user_mailer` directory.
925
952
 
926
- When you generated your mailer, the generator creates stub fixtures for each of the mailers actions. If you didn't use the generator you'll have to make those files yourself.
953
+ If you generated your mailer, the generator does not create stub fixtures for the mailers actions. You'll have to create those files yourself as described above.
927
954
 
928
955
  #### The Basic Test Case
929
956
 
@@ -933,12 +960,11 @@ Here's a unit test to test a mailer named `UserMailer` whose action `invite` is
933
960
  require 'test_helper'
934
961
 
935
962
  class UserMailerTest < ActionMailer::TestCase
936
- tests UserMailer
937
963
  test "invite" do
938
964
  # Send the email, then test that it got queued
939
965
  email = UserMailer.create_invite('me@example.com',
940
- 'friend@example.com', Time.now).deliver
941
- assert !ActionMailer::Base.deliveries.empty?
966
+ 'friend@example.com', Time.now).deliver_now
967
+ assert_not ActionMailer::Base.deliveries.empty?
942
968
 
943
969
  # Test the body of the sent email contains what we expect it to
944
970
  assert_equal ['me@example.com'], email.from
@@ -992,7 +1018,102 @@ class UserControllerTest < ActionController::TestCase
992
1018
 
993
1019
  assert_equal "You have been invited by me@example.com", invite_email.subject
994
1020
  assert_equal 'friend@example.com', invite_email.to[0]
995
- assert_match(/Hi friend@example.com/, invite_email.body)
1021
+ assert_match(/Hi friend@example.com/, invite_email.body.to_s)
1022
+ end
1023
+ end
1024
+ ```
1025
+
1026
+ Testing helpers
1027
+ ---------------
1028
+
1029
+ In order to test helpers, all you need to do is check that the output of the
1030
+ helper method matches what you'd expect. Tests related to the helpers are
1031
+ located under the `test/helpers` directory.
1032
+
1033
+ A helper test looks like so:
1034
+
1035
+ ```ruby
1036
+ require 'test_helper'
1037
+
1038
+ class UserHelperTest < ActionView::TestCase
1039
+ end
1040
+ ```
1041
+
1042
+ A helper is just a simple module where you can define methods which are
1043
+ available into your views. To test the output of the helper's methods, you just
1044
+ have to use a mixin like this:
1045
+
1046
+ ```ruby
1047
+ class UserHelperTest < ActionView::TestCase
1048
+ include UserHelper
1049
+
1050
+ test "should return the user name" do
1051
+ # ...
1052
+ end
1053
+ end
1054
+ ```
1055
+
1056
+ Moreover, since the test class extends from `ActionView::TestCase`, you have
1057
+ access to Rails' helper methods such as `link_to` or `pluralize`.
1058
+
1059
+ Testing Jobs
1060
+ ------------
1061
+
1062
+ Since your custom jobs can be queued at different levels inside your application,
1063
+ you'll need to test both jobs themselves (their behavior when they get enqueued)
1064
+ and that other entities correctly enqueue them.
1065
+
1066
+ ### A Basic Test Case
1067
+
1068
+ By default, when you generate a job, an associated test will be generated as well
1069
+ under the `test/jobs` directory. Here's an example test with a billing job:
1070
+
1071
+ ```ruby
1072
+ require 'test_helper'
1073
+
1074
+ class BillingJobTest < ActiveJob::TestCase
1075
+ test 'that account is charged' do
1076
+ BillingJob.perform_now(account, product)
1077
+ assert account.reload.charged_for?(product)
1078
+ end
1079
+ end
1080
+ ```
1081
+
1082
+ This test is pretty simple and only asserts that the job get the work done
1083
+ as expected.
1084
+
1085
+ By default, `ActiveJob::TestCase` will set the queue adapter to `:test` so that
1086
+ your jobs are performed inline. It will also ensure that all previously performed
1087
+ and enqueued jobs are cleared before any test run so you can safely assume that
1088
+ no jobs have already been executed in the scope of each test.
1089
+
1090
+ ### Custom Assertions And Testing Jobs Inside Other Components
1091
+
1092
+ Active Job ships with a bunch of custom assertions that can be used to lessen
1093
+ the verbosity of tests:
1094
+
1095
+ | Assertion | Purpose |
1096
+ | -------------------------------------- | ------- |
1097
+ | `assert_enqueued_jobs(number)` | Asserts that the number of enqueued jobs matches the given number. |
1098
+ | `assert_performed_jobs(number)` | Asserts that the number of performed jobs matches the given number. |
1099
+ | `assert_no_enqueued_jobs { ... }` | Asserts that no jobs have been enqueued. |
1100
+ | `assert_no_performed_jobs { ... }` | Asserts that no jobs have been performed. |
1101
+ | `assert_enqueued_with([args]) { ... }` | Asserts that the job passed in the block has been enqueued with the given arguments. |
1102
+ | `assert_performed_with([args]) { ... }`| Asserts that the job passed in the block has been performed with the given arguments. |
1103
+
1104
+ It's a good practice to ensure that your jobs correctly get enqueued or performed
1105
+ wherever you invoke them (e.g. inside your controllers). This is precisely where
1106
+ the custom assertions provided by Active Job are pretty useful. For instance,
1107
+ within a model:
1108
+
1109
+ ```ruby
1110
+ require 'test_helper'
1111
+
1112
+ class ProductTest < ActiveJob::TestCase
1113
+ test 'billing job scheduling' do
1114
+ assert_enqueued_with(job: BillingJob) do
1115
+ product.charge(account)
1116
+ end
996
1117
  end
997
1118
  end
998
1119
  ```
@@ -1000,11 +1121,12 @@ end
1000
1121
  Other Testing Approaches
1001
1122
  ------------------------
1002
1123
 
1003
- The built-in `test/unit` based testing is not the only way to test Rails applications. Rails developers have come up with a wide variety of other approaches and aids for testing, including:
1124
+ The built-in `minitest` based testing is not the only way to test Rails applications. Rails developers have come up with a wide variety of other approaches and aids for testing, including:
1004
1125
 
1005
1126
  * [NullDB](http://avdi.org/projects/nulldb/), a way to speed up testing by avoiding database use.
1006
1127
  * [Factory Girl](https://github.com/thoughtbot/factory_girl/tree/master), a replacement for fixtures.
1007
- * [Machinist](https://github.com/notahat/machinist/tree/master), another replacement for fixtures.
1128
+ * [Fixture Builder](https://github.com/rdy/fixture_builder), a tool that compiles Ruby factories into fixtures before a test run.
1008
1129
  * [MiniTest::Spec Rails](https://github.com/metaskills/minitest-spec-rails), use the MiniTest::Spec DSL within your rails tests.
1009
1130
  * [Shoulda](http://www.thoughtbot.com/projects/shoulda), an extension to `test/unit` with additional helpers, macros, and assertions.
1010
1131
  * [RSpec](http://relishapp.com/rspec), a behavior-driven development framework
1132
+ * [Capybara](http://jnicklas.github.com/capybara/), Acceptance test framework for web applications