rspec-rails 3.0.2 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +3 -1
  5. data/Capybara.md +6 -55
  6. data/Changelog.md +805 -47
  7. data/{License.txt → LICENSE.md} +5 -3
  8. data/README.md +278 -444
  9. data/lib/generators/rspec/channel/channel_generator.rb +12 -0
  10. data/lib/generators/rspec/{observer/templates/observer_spec.rb → channel/templates/channel_spec.rb.erb} +1 -1
  11. data/lib/generators/rspec/controller/controller_generator.rb +24 -7
  12. data/lib/generators/rspec/controller/templates/controller_spec.rb +3 -3
  13. data/lib/generators/rspec/controller/templates/request_spec.rb +19 -0
  14. data/lib/generators/rspec/controller/templates/routing_spec.rb +13 -0
  15. data/lib/generators/rspec/controller/templates/view_spec.rb +1 -1
  16. data/lib/generators/rspec/feature/feature_generator.rb +15 -2
  17. data/lib/generators/rspec/feature/templates/feature_singular_spec.rb +5 -0
  18. data/lib/generators/rspec/feature/templates/feature_spec.rb +1 -1
  19. data/lib/generators/rspec/generator/generator_generator.rb +24 -0
  20. data/lib/generators/rspec/generator/templates/generator_spec.rb +5 -0
  21. data/lib/generators/rspec/helper/helper_generator.rb +2 -2
  22. data/lib/generators/rspec/helper/templates/helper_spec.rb +1 -1
  23. data/lib/generators/rspec/install/install_generator.rb +41 -7
  24. data/lib/generators/rspec/install/templates/spec/rails_helper.rb +63 -22
  25. data/lib/generators/rspec/job/job_generator.rb +13 -0
  26. data/lib/generators/rspec/job/templates/job_spec.rb.erb +7 -0
  27. data/lib/generators/rspec/mailbox/mailbox_generator.rb +14 -0
  28. data/lib/generators/rspec/mailbox/templates/mailbox_spec.rb.erb +7 -0
  29. data/lib/generators/rspec/mailer/mailer_generator.rb +12 -3
  30. data/lib/generators/rspec/mailer/templates/mailer_spec.rb +2 -2
  31. data/lib/generators/rspec/mailer/templates/preview.rb +13 -0
  32. data/lib/generators/rspec/model/model_generator.rb +20 -6
  33. data/lib/generators/rspec/model/templates/fixtures.yml +1 -1
  34. data/lib/generators/rspec/model/templates/model_spec.rb +1 -1
  35. data/lib/generators/rspec/request/request_generator.rb +17 -0
  36. data/lib/generators/rspec/request/templates/request_spec.rb +10 -0
  37. data/lib/generators/rspec/scaffold/scaffold_generator.rb +90 -113
  38. data/lib/generators/rspec/scaffold/templates/api_controller_spec.rb +129 -0
  39. data/lib/generators/rspec/scaffold/templates/api_request_spec.rb +131 -0
  40. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +46 -64
  41. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +11 -7
  42. data/lib/generators/rspec/scaffold/templates/index_spec.rb +4 -3
  43. data/lib/generators/rspec/scaffold/templates/new_spec.rb +4 -4
  44. data/lib/generators/rspec/scaffold/templates/request_spec.rb +138 -0
  45. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +18 -11
  46. data/lib/generators/rspec/scaffold/templates/show_spec.rb +3 -3
  47. data/lib/generators/rspec/system/system_generator.rb +24 -0
  48. data/lib/generators/rspec/system/templates/system_spec.rb +9 -0
  49. data/lib/generators/rspec/view/templates/view_spec.rb +1 -1
  50. data/lib/generators/rspec/view/view_generator.rb +4 -4
  51. data/lib/generators/rspec.rb +30 -11
  52. data/lib/rspec/rails/active_record.rb +25 -0
  53. data/lib/rspec/rails/adapters.rb +46 -29
  54. data/lib/rspec/rails/configuration.rb +165 -41
  55. data/lib/rspec/rails/example/channel_example_group.rb +93 -0
  56. data/lib/rspec/rails/example/controller_example_group.rb +185 -149
  57. data/lib/rspec/rails/example/feature_example_group.rb +43 -23
  58. data/lib/rspec/rails/example/helper_example_group.rb +28 -25
  59. data/lib/rspec/rails/example/job_example_group.rb +23 -0
  60. data/lib/rspec/rails/example/mailbox_example_group.rb +80 -0
  61. data/lib/rspec/rails/example/mailer_example_group.rb +27 -22
  62. data/lib/rspec/rails/example/model_example_group.rb +9 -6
  63. data/lib/rspec/rails/example/rails_example_group.rb +9 -2
  64. data/lib/rspec/rails/example/request_example_group.rb +21 -17
  65. data/lib/rspec/rails/example/routing_example_group.rb +47 -39
  66. data/lib/rspec/rails/example/system_example_group.rb +180 -0
  67. data/lib/rspec/rails/example/view_example_group.rb +179 -134
  68. data/lib/rspec/rails/example.rb +4 -0
  69. data/lib/rspec/rails/extensions/active_record/proxy.rb +5 -11
  70. data/lib/rspec/rails/feature_check.rb +51 -0
  71. data/lib/rspec/rails/file_fixture_support.rb +18 -0
  72. data/lib/rspec/rails/fixture_file_upload_support.rb +45 -0
  73. data/lib/rspec/rails/fixture_support.rb +70 -14
  74. data/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +180 -0
  75. data/lib/rspec/rails/matchers/action_cable/have_streams.rb +58 -0
  76. data/lib/rspec/rails/matchers/action_cable.rb +70 -0
  77. data/lib/rspec/rails/matchers/action_mailbox.rb +73 -0
  78. data/lib/rspec/rails/matchers/active_job.rb +526 -0
  79. data/lib/rspec/rails/matchers/base_matcher.rb +179 -0
  80. data/lib/rspec/rails/matchers/be_a_new.rb +70 -64
  81. data/lib/rspec/rails/matchers/be_new_record.rb +25 -20
  82. data/lib/rspec/rails/matchers/be_valid.rb +39 -34
  83. data/lib/rspec/rails/matchers/have_enqueued_mail.rb +259 -0
  84. data/lib/rspec/rails/matchers/have_http_status.rb +359 -333
  85. data/lib/rspec/rails/matchers/have_rendered.rb +55 -32
  86. data/lib/rspec/rails/matchers/redirect_to.rb +30 -27
  87. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  88. data/lib/rspec/rails/matchers/routing_matchers.rb +107 -101
  89. data/lib/rspec/rails/matchers/send_email.rb +122 -0
  90. data/lib/rspec/rails/matchers.rb +21 -12
  91. data/lib/rspec/rails/tasks/rspec.rake +9 -17
  92. data/lib/rspec/rails/vendor/capybara.rb +10 -11
  93. data/lib/rspec/rails/version.rb +1 -1
  94. data/lib/rspec/rails/view_assigns.rb +1 -20
  95. data/lib/rspec/rails/view_path_builder.rb +29 -0
  96. data/lib/rspec/rails/view_rendering.rb +89 -27
  97. data/lib/rspec/rails/view_spec_methods.rb +56 -0
  98. data/lib/rspec/rails.rb +9 -1
  99. data/lib/rspec-rails.rb +83 -3
  100. data.tar.gz.sig +0 -0
  101. metadata +108 -78
  102. metadata.gz.sig +3 -2
  103. data/lib/generators/rspec/integration/integration_generator.rb +0 -17
  104. data/lib/generators/rspec/integration/templates/request_spec.rb +0 -10
  105. data/lib/generators/rspec/observer/observer_generator.rb +0 -13
data/README.md CHANGED
@@ -1,546 +1,380 @@
1
- # rspec-rails [![Build Status](https://secure.travis-ci.org/rspec/rspec-rails.png?branch=master)](http://travis-ci.org/rspec/rspec-rails) [![Code Climate](https://codeclimate.com/github/rspec/rspec-rails.png)](https://codeclimate.com/github/rspec/rspec-rails)
2
- **rspec-rails** is a testing framework for Rails 3.x and 4.x.
3
-
4
- Use **[rspec-rails 1.x](http://github.com/dchelimsky/rspec-rails)** for Rails
5
- 2.x.
1
+ # rspec-rails [![Code Climate][]][code-climate] [![Gem Version][]][gem-version]
2
+
3
+ `rspec-rails` brings the [RSpec][] testing framework to [Ruby on Rails][]
4
+ as a drop-in alternative to its default testing framework, Minitest.
5
+
6
+ In RSpec, tests are not just scripts that verify your application code.
7
+ They’re also specifications (or _specs,_ for short):
8
+ detailed explanations of how the application is supposed to behave,
9
+ expressed in plain English.
10
+
11
+ According to [RSpec Rails new versioning strategy][] use:
12
+ * **[`rspec-rails` 7.x][]** for Rails 7.x.
13
+ * **[`rspec-rails` 6.x][]** for Rails 6.1, 7.0 or 7.1.
14
+ * **[`rspec-rails` 5.x][]** for Rails 5.2 or 6.x.
15
+ * **[`rspec-rails` 4.x][]** for Rails from 5.x or 6.x.
16
+ * **[`rspec-rails` 3.x][]** for Rails earlier than 5.0.
17
+ * **[`rspec-rails` 1.x][]** for Rails 2.x.
18
+
19
+ [Code Climate]: https://codeclimate.com/github/rspec/rspec-rails.svg
20
+ [code-climate]: https://codeclimate.com/github/rspec/rspec-rails
21
+ [Gem Version]: https://badge.fury.io/rb/rspec-rails.svg
22
+ [gem-version]: https://badge.fury.io/rb/rspec-rails
23
+ [RSpec]: https://rspec.info/
24
+ [Ruby on Rails]: https://rubyonrails.org/
25
+ [`rspec-rails` 1.x]: https://github.com/dchelimsky/rspec-rails
26
+ [`rspec-rails` 3.x]: https://github.com/rspec/rspec-rails/tree/3-9-maintenance
27
+ [`rspec-rails` 4.x]: https://github.com/rspec/rspec-rails/tree/4-1-maintenance
28
+ [`rspec-rails` 5.x]: https://github.com/rspec/rspec-rails/tree/5-1-maintenance
29
+ [`rspec-rails` 6.x]: https://github.com/rspec/rspec-rails/tree/6-1-maintenance
30
+ [`rspec-rails` 7.x]: https://github.com/rspec/rspec-rails/tree/7-1-maintenance
31
+ [RSpec Rails new versioning strategy]: https://github.com/rspec/rspec-rails/blob/main/rfcs/versioning-strategy.md
6
32
 
7
33
  ## Installation
8
34
 
9
- Add `rspec-rails` to **both** the `:development` and `:test` groups in the
10
- `Gemfile`:
11
-
12
- ```ruby
13
- group :development, :test do
14
- gem 'rspec-rails', '~> 3.0.0'
15
- end
16
- ```
17
-
18
- Download and install by running:
19
-
20
- ```
21
- bundle install
22
- ```
23
-
24
- Initialize the `spec/` directory (where specs will reside) with:
25
-
26
- ```
27
- rails generate rspec:install
28
- ```
29
-
30
- This adds the following files which are used for configuration:
35
+ **IMPORTANT** This README / branch refers to the 7.1.x stable release series, only bugfixes from this series will
36
+ be added here. See the [`main` branch on Github](https://github.com/rspec/rspec-rails/tree/main) if you want or
37
+ require the latest unstable features.
31
38
 
32
- - `.rspec`
33
- - `spec/spec_helper.rb`
34
- - `spec/rails_helper.rb`
39
+ 1. Add `rspec-rails` to **both** the `:development` and `:test` groups
40
+ of your app’s `Gemfile`:
35
41
 
36
- Check the comments in each file for more information.
42
+ ```ruby
43
+ # Run against this stable release
44
+ group :development, :test do
45
+ gem 'rspec-rails', '~> 7.0.0'
46
+ end
37
47
 
38
- Use the `rspec` command to run your specs:
39
-
40
- ```
41
- bundle exec rspec
42
- ```
48
+ # Or, run against the main branch
49
+ group :development, :test do
50
+ gem 'rspec-rails', git: 'https://github.com/rspec/rspec-rails'
51
+ end
52
+ ```
43
53
 
44
- By default the above will run all `_spec.rb` files in the `spec` directory. For
45
- more details about this see the [RSpec spec file
46
- docs](https://www.relishapp.com/rspec/rspec-core/docs/spec-files).
54
+ (Adding it to the `:development` group is not strictly necessary,
55
+ but without it, generators and rake tasks must be preceded by `RAILS_ENV=test`.)
47
56
 
48
- To run only a subset of these specs use the following command:
57
+ 2. Then, in your project directory:
49
58
 
50
- ```
51
- # Run only model specs
52
- bundle exec rspec spec/models
59
+ ```sh
60
+ # Download and install
61
+ $ bundle install
53
62
 
54
- # Run only specs for AccountsController
55
- bundle exec rspec spec/controllers/accounts_controller_spec.rb
56
- ```
63
+ # Generate boilerplate configuration files
64
+ # (check the comments in each generated file for more information)
65
+ $ rails generate rspec:install
66
+ create .rspec
67
+ create spec
68
+ create spec/spec_helper.rb
69
+ create spec/rails_helper.rb
70
+ ```
57
71
 
58
- Specs can also be run via `rake spec`, though this command may be slower to
59
- start than the `rspec` command.
72
+ ## Upgrading
60
73
 
61
- In Rails 4, you may want to create a binstub for the `rspec` command so it can
62
- be run via `bin/rspec`:
74
+ If your project is already using an older version of `rspec-rails`,
75
+ upgrade to the latest version with:
63
76
 
77
+ ```sh
78
+ $ bundle update rspec-rails
64
79
  ```
65
- bundle binstubs rspec-core
66
- ```
67
-
68
- ### Upgrade Note
69
-
70
- For detailed information on the general RSpec 3.x upgrade process see the
71
- [RSpec Upgrade docs](https://relishapp.com/rspec/docs/upgrade).
72
-
73
- There are three particular `rspec-rails` specific changes to be aware of:
74
-
75
- 1. [The default helper files created in RSpec 3.x have changed](https://www.relishapp.com/rspec/rspec-rails/docs/upgrade#default-helper-files)
76
- 2. [File-type inference disabled by default](https://www.relishapp.com/rspec/rspec-rails/docs/upgrade#file-type-inference-disabled)
77
- 3. [Rails 4.x `ActiveRecord::Migration` pending migration checks](https://www.relishapp.com/rspec/rspec-rails/docs/upgrade#pending-migration-checks)
78
- 4. Extraction of `stub_model` and `mock_model` to
79
- [`rspec-activemodel-mocks`](https://github.com/rspec/rspec-activemodel-mocks)
80
80
 
81
- Please see the [RSpec Rails Upgrade
82
- docs](https://www.relishapp.com/rspec/rspec-rails/docs/upgrade) for full
83
- details.
81
+ RSpec follows [semantic versioning](https://semver.org/),
82
+ which means that “major version” upgrades (_e.g.,_ 2.x 3.x)
83
+ come with **breaking changes**.
84
+ If you’re upgrading from version 2.x or below,
85
+ read the [`rspec-rails` upgrade notes][] to find out what to watch out for.
84
86
 
85
- **NOTE:** Generators run in RSpec 3.x will now require `rails_helper` instead
86
- of `spec_helper`.
87
+ Be sure to check the general [RSpec upgrade notes][] as well.
87
88
 
88
- ### Generators
89
+ [`rspec-rails` upgrade notes]: https://rspec.info/features/7-1/rspec-rails/upgrade
90
+ [RSpec upgrade notes]: https://rspec.info/upgrading-from-rspec-2/
89
91
 
90
- Once installed, RSpec will generate spec files instead of Test::Unit test files
91
- when commands like `rails generate model` and `rails generate controller` are
92
- used.
92
+ ## Usage
93
93
 
94
- You may also invoke RSpec generators independently. For instance,
95
- running `rails generate rspec:model` will generate a model spec. For more
96
- information, see [list of all
97
- generators](https://www.relishapp.com/rspec/rspec-rails/docs/generators).
94
+ ### Creating boilerplate specs with `rails generate`
98
95
 
99
- ## Model Specs
96
+ ```sh
97
+ # RSpec hooks into built-in generators
98
+ $ rails generate model user
99
+ invoke active_record
100
+ create db/migrate/20181017040312_create_users.rb
101
+ create app/models/user.rb
102
+ invoke rspec
103
+ create spec/models/user_spec.rb
100
104
 
101
- Use model specs to describe behavior of models (usually ActiveRecord-based) in
102
- the application.
105
+ # RSpec also provides its own spec file generators
106
+ $ rails generate rspec:model user
107
+ create spec/models/user_spec.rb
103
108
 
104
- Model specs default to residing in the `spec/models` folder. Tagging any
105
- context with the metadata `:type => :model` treats it's examples as model
106
- specs.
107
-
108
- For example:
109
-
110
- ```ruby
111
- require "rails_helper"
112
-
113
- RSpec.describe User, :type => :model do
114
- it "orders by last name" do
115
- lindeman = User.create!(first_name: "Andy", last_name: "Lindeman")
116
- chelimsky = User.create!(first_name: "David", last_name: "Chelimsky")
117
-
118
- expect(User.ordered_by_last_name).to eq([chelimsky, lindeman])
119
- end
120
- end
109
+ # List all RSpec generators
110
+ $ rails generate --help | grep rspec
121
111
  ```
122
112
 
123
- For more information, see [cucumber scenarios for model
124
- specs](https://www.relishapp.com/rspec/rspec-rails/docs/model-specs).
113
+ ### Running specs
125
114
 
126
- ## Controller Specs
115
+ ```sh
116
+ # Default: Run all spec files (i.e., those matching spec/**/*_spec.rb)
117
+ $ bundle exec rspec
127
118
 
128
- Use controller specs to describe behavior of Rails controllers.
119
+ # Run all spec files in a single directory (recursively)
120
+ $ bundle exec rspec spec/models
129
121
 
130
- Controller specs default to residing in the `spec/controllers` folder. Tagging
131
- any context with the metadata `:type => :controller` treats it's examples as
132
- controller specs.
122
+ # Run a single spec file
123
+ $ bundle exec rspec spec/controllers/accounts_controller_spec.rb
133
124
 
134
- For example:
125
+ # Run a single example from a spec file (by line number)
126
+ $ bundle exec rspec spec/controllers/accounts_controller_spec.rb:8
135
127
 
136
- ```ruby
137
- require "rails_helper"
138
-
139
- RSpec.describe PostsController, :type => :controller do
140
- describe "GET #index" do
141
- it "responds successfully with an HTTP 200 status code" do
142
- get :index
143
- expect(response).to be_success
144
- expect(response).to have_http_status(200)
145
- end
146
-
147
- it "renders the index template" do
148
- get :index
149
- expect(response).to render_template("index")
150
- end
151
-
152
- it "loads all of the posts into @posts" do
153
- post1, post2 = Post.create!, Post.create!
154
- get :index
155
-
156
- expect(assigns(:posts)).to match_array([post1, post2])
157
- end
158
- end
159
- end
128
+ # See all options for running specs
129
+ $ bundle exec rspec --help
160
130
  ```
161
131
 
162
- For more information, see [cucumber scenarios for controller
163
- specs](https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs).
132
+ **Optional:** If `bundle exec rspec` is too verbose for you,
133
+ you can generate a binstub at `bin/rspec` and use that instead:
164
134
 
165
- **Note:** To encourage more isolated testing, views are not rendered by default
166
- in controller specs. If you are verifying discrete view logic, use a [view
167
- spec](#view-specs). If you are verifying the behaviour of a controller and view
168
- together, consider a [request spec](#request-specs). You can use
169
- [render\_views](https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs/render-views)
170
- if you must verify the rendered view contents within a controller spec, but
171
- this is not recommended.
135
+ ```sh
136
+ $ bundle binstubs rspec-core
137
+ ```
172
138
 
173
- ## Request Specs
139
+ ## RSpec DSL Basics (or, how do I write a spec?)
174
140
 
175
- Use request specs to specify one or more request/response cycles from end to
176
- end using a black box approach.
177
-
178
- Request specs default to residing in the `spec/requests`, `spec/api`, and
179
- `spec/integration` directories. Tagging any context with the metadata `:type =>
180
- :request` treats it's examples as request specs.
181
-
182
- Request specs mix in behavior from
183
- [ActionDispatch::Integration::Runner](http://api.rubyonrails.org/classes/ActionDispatch/Integration/Runner.html),
184
- which is the basis for [Rails' integration
185
- tests](http://guides.rubyonrails.org/testing.html#integration-testing).
141
+ In RSpec, application behavior is described
142
+ **first in (almost) plain English, then again in test code**, like so:
186
143
 
187
144
  ```ruby
188
- require 'rails_helper'
189
-
190
- RSpec.describe "home page", :type => :request do
191
- it "displays the user's username after successful login" do
192
- user = User.create!(:username => "jdoe", :password => "secret")
193
- get "/login"
194
- assert_select "form.login" do
195
- assert_select "input[name=?]", "username"
196
- assert_select "input[name=?]", "password"
197
- assert_select "input[type=?]", "submit"
145
+ RSpec.describe 'Post' do #
146
+ context 'before publication' do # (almost) plain English
147
+ it 'cannot have comments' do #
148
+ expect { Post.create.comments.create! }.to raise_error(ActiveRecord::RecordInvalid) # test code
198
149
  end
199
-
200
- post "/login", :username => "jdoe", :password => "secret"
201
- assert_select ".header .username", :text => "jdoe"
202
150
  end
203
151
  end
204
152
  ```
205
153
 
206
- The above example uses only standard Rails and RSpec API's, but many
207
- RSpec/Rails users like to use extension libraries like
208
- [FactoryGirl](https://github.com/thoughtbot/factory_girl) and
209
- [Capybara](https://github.com/jnicklas/capybara):
210
-
211
- ```ruby
212
- require 'rails_helper'
213
-
214
- RSpec.describe "home page", :type => :request do
215
- it "displays the user's username after successful login" do
216
- user = FactoryGirl.create(:user, :username => "jdoe", :password => "secret")
217
- visit "/login"
218
- fill_in "Username", :with => "jdoe"
219
- fill_in "Password", :with => "secret"
220
- click_button "Log in"
154
+ Running `rspec` will execute this test code,
155
+ and then use the plain-English descriptions
156
+ to generate a report of where the application
157
+ conforms to (or fails to meet) the spec:
221
158
 
222
- expect(page).to have_selector(".header .username", :text => "jdoe")
223
- end
224
- end
225
159
  ```
160
+ $ rspec --format documentation spec/models/post_spec.rb
226
161
 
227
- FactoryGirl decouples this example from changes to validation requirements,
228
- which can be encoded into the underlying factory definition without requiring
229
- changes to this example.
162
+ Post
163
+ before publication
164
+ cannot have comments
230
165
 
231
- Among other benefits, Capybara binds the form post to the generated HTML, which
232
- means we don't need to specify them separately. Note that Capybara's DSL as
233
- shown is, by default, only available in specs in the spec/features directory.
234
- For more information, see the [Capybara integration
235
- docs](http://rubydoc.info/gems/rspec-rails/file/Capybara.md).
166
+ Failures:
236
167
 
237
- There are several other Ruby libs that implement the factory pattern or provide
238
- a DSL for request specs (a.k.a. acceptance or integration specs), but
239
- FactoryGirl and Capybara seem to be the most widely used. Whether you choose
240
- these or other libs, we strongly recommend using something for each of these
241
- roles.
168
+ 1) Post before publication cannot have comments
169
+ Failure/Error: expect { Post.create.comments.create! }.to raise_error(ActiveRecord::RecordInvalid)
170
+ expected ActiveRecord::RecordInvalid but nothing was raised
171
+ # ./spec/models/post.rb:4:in `block (3 levels) in <top (required)>'
242
172
 
243
- ## Feature Specs
173
+ Finished in 0.00527 seconds (files took 0.29657 seconds to load)
174
+ 1 example, 1 failure
244
175
 
245
- Feature specs test your application from the outside by simulating a browser.
246
- [`capybara`](https://github.com/jnicklas/capybara) is used to manage the
247
- simulated browser.
176
+ Failed examples:
248
177
 
249
- Feature specs default to residing in the `spec/features` folder. Tagging any
250
- context with the metadata `:type => :feature` treats it's examples as feature
251
- specs.
252
-
253
- Feature specs mix in functionality from the capybara gem, thus they require
254
- `capybara` to use. To use feature specs, add `capybara` to the `Gemfile`:
255
-
256
- ```ruby
257
- gem "capybara"
178
+ rspec ./spec/models/post_spec.rb:3 # Post before publication cannot have comments
258
179
  ```
259
180
 
260
- For more information, see the [cucumber scenarios for feature
261
- specs](https://www.relishapp.com/rspec/rspec-rails/v/3-0/docs/feature-specs/feature-spec).
262
-
263
- ## View specs
181
+ For an in-depth look at the RSpec DSL, including lots of examples,
182
+ read the official Cucumber documentation for [RSpec Core][].
264
183
 
265
- View specs default to residing in the `spec/views` folder. Tagging any context
266
- with the metadata `:type => :view` treats it's examples as view specs.
184
+ [RSpec Core]: https://rspec.info/features/3-12/rspec-core
267
185
 
268
- View specs mix in `ActionView::TestCase::Behavior`.
186
+ ### Helpful Rails Matchers
269
187
 
270
- ```ruby
271
- require 'rails_helper'
272
-
273
- RSpec.describe "events/index", :type => :view do
274
- it "renders _event partial for each event" do
275
- assign(:events, [double(Event), double(Event)])
276
- render
277
- expect(view).to render_template(:partial => "_event", :count => 2)
278
- end
279
- end
188
+ In RSpec, assertions are called _expectations,_
189
+ and every expectation is built around a _matcher._
190
+ When you `expect(a).to eq(b)`, you’re using the `eq` matcher.
280
191
 
281
- RSpec.describe "events/show", :type => :view do
282
- it "displays the event location" do
283
- assign(:event, Event.new(:location => "Chicago"))
284
- render
285
- expect(rendered).to include("Chicago")
286
- end
287
- end
288
- ```
289
-
290
- View specs infer the controller name and path from the path to the view
291
- template. e.g. if the template is `events/index.html.erb` then:
292
-
293
- ```ruby
294
- controller.controller_path == "events"
295
- controller.request.path_parameters[:controller] == "events"
296
- ```
192
+ In addition to [the matchers that come standard in RSpec][],
193
+ here are some extras that make it easier
194
+ to test the various parts of a Rails system:
297
195
 
298
- This means that most of the time you don't need to set these values. When
299
- spec'ing a partial that is included across different controllers, you _may_
300
- need to override these values before rendering the view.
196
+ | RSpec matcher | Delegates to | Available in | Notes |
197
+ | ------------------------ | ------------------- | ------------------------------- | -------------------------------------------------------- |
198
+ | [`be_a_new`][] | | all | primarily intended for controller specs |
199
+ | [`render_template`][] | `assert_template` | request / controller / view | use with `expect(response).to` |
200
+ | [`redirect_to`][] | `assert_redirect` | request / controller | use with `expect(response).to` |
201
+ | [`route_to`] | `assert_recognizes` | routing / controller | use with `expect(...).to route_to` |
202
+ | [`be_routable`] | | routing / controller | use with `expect(...).not_to be_routable` |
203
+ | [`have_http_status`][] | | request / controller / feature | |
204
+ | [`match_array`][] | | all | for comparing arrays of ActiveRecord objects |
205
+ | [`have_been_enqueued`][] | | all | requires config: `ActiveJob::Base.queue_adapter = :test` |
206
+ | [`have_enqueued_job`][] | | all | requires config: `ActiveJob::Base.queue_adapter = :test` |
301
207
 
302
- To provide a layout for the render, you'll need to specify _both_ the template
303
- and the layout explicitly. For example:
208
+ Follow the links above for examples of how each matcher is used.
304
209
 
305
- ```ruby
306
- render :template => "events/show", :layout => "layouts/application"
307
- ```
210
+ [the matchers that come standard in RSpec]: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers
211
+ [`be_a_new`]: https://rspec.info/features/7-1/rspec-rails/matchers/new-record-matcher
212
+ [`render_template`]: https://rspec.info/features/7-1/rspec-rails/matchers/render-template-matcher
213
+ [`redirect_to`]: https://rspec.info/features/7-1/rspec-rails/matchers/redirect-to-matcher
214
+ [`route_to`]: https://rspec.info/features/7-1/rspec-rails/routing-specs/route-to-matcher
215
+ [`be_routable`]: https://rspec.info/features/7-1/rspec-rails/routing-specs/be-routable-matcher
216
+ [`have_http_status`]: https://rspec.info/features/7-1/rspec-rails/matchers/have-http-status-matcher
217
+ [`match_array`]: https://rspec.info/features/7-1/rspec-rails/matchers/relation-match-array
218
+ [`have_been_enqueued`]: https://rspec.info/features/7-1/rspec-rails/matchers/have-been-enqueued-matcher
219
+ [`have_enqueued_job`]: https://rspec.info/features/7-1/rspec-rails/matchers/have-enqueued-job-matcher
308
220
 
309
- ### `assign(key, val)`
221
+ ### What else does RSpec Rails add?
310
222
 
311
- Use this to assign values to instance variables in the view:
223
+ For a comprehensive look at RSpec Rails’ features,
224
+ read the [official Cucumber documentation][].
312
225
 
313
- ```ruby
314
- assign(:widget, Widget.new)
315
- render
316
- ```
226
+ [official Cucumber documentation]: https://rspec.info/features/7-1/rspec-rails
317
227
 
318
- The code above assigns `Widget.new` to the `@widget` variable in the view, and
319
- then renders the view.
228
+ ## What tests should I write?
320
229
 
321
- Note that because view specs mix in `ActionView::TestCase` behavior, any
322
- instance variables you set will be transparently propagated into your views
323
- (similar to how instance variables you set in controller actions are made
324
- available in views). For example:
230
+ RSpec Rails defines ten different _types_ of specs
231
+ for testing different parts of a typical Rails application.
232
+ Each one inherits from one of Rails’ built-in `TestCase` classes,
233
+ meaning the helper methods provided by default in Rails tests
234
+ are available in RSpec, as well.
325
235
 
326
- ```ruby
327
- @widget = Widget.new
328
- render # @widget is available inside the view
329
- ```
236
+ | Spec type | Corresponding Rails test class |
237
+ | -------------- | -------------------------------- |
238
+ | [model][] | |
239
+ | [controller][] | [`ActionController::TestCase`][] |
240
+ | [mailer][] | `ActionMailer::TestCase` |
241
+ | [job][] | |
242
+ | [view][] | `ActionView::TestCase` |
243
+ | [routing][] | |
244
+ | [helper][] | `ActionView::TestCase` |
245
+ | [request][] | [`ActionDispatch::IntegrationTest`][] |
246
+ | [feature][] | |
247
+ | [system][] | [`ActionDispatch::SystemTestCase`][] |
330
248
 
331
- RSpec doesn't officially support this pattern, which only works as a
332
- side-effect of the inclusion of `ActionView::TestCase`. Be aware that it may be
333
- made unavailable in the future.
249
+ Follow the links above to see examples of each spec type,
250
+ or for official Rails API documentation on the given `TestCase` class.
334
251
 
335
- #### Upgrade note
252
+ > **Note: This is not a checklist.**
253
+ >
254
+ > Ask a hundred developers how to test an application,
255
+ > and you’ll get a hundred different answers.
256
+ >
257
+ > RSpec Rails provides thoughtfully selected features
258
+ > to encourage good testing practices, but there’s no “right” way to do it.
259
+ > Ultimately, it’s up to you to decide how your test suite will be composed.
260
+
261
+ When creating a spec file,
262
+ assign it a type in the top-level `describe` block, like so:
336
263
 
337
264
  ```ruby
338
- # rspec-rails-1.x
339
- assigns[key] = value
340
-
341
- # rspec-rails-2.x+
342
- assign(key, value)
343
- ```
265
+ # spec/models/user_spec.rb
344
266
 
345
- ### `rendered`
346
-
347
- This represents the rendered view.
348
-
349
- ```ruby
350
- render
351
- expect(rendered).to match /Some text expected to appear on the page/
267
+ RSpec.describe User, type: :model do
268
+ ...
352
269
  ```
353
270
 
354
- #### Upgrade note
271
+ [request]: https://rspec.info/features/7-1/rspec-rails/request-specs/request-spec
272
+ [feature]: https://rspec.info/features/7-1/rspec-rails/feature-specs/feature-spec
273
+ [system]: https://rspec.info/features/7-1/rspec-rails/system-specs/system-specs
274
+ [model]: https://rspec.info/features/7-1/rspec-rails/model-specs
275
+ [controller]: https://rspec.info/features/7-1/rspec-rails/controller-specs
276
+ [mailer]: https://rspec.info/features/7-1/rspec-rails/mailer-specs
277
+ [job]: https://rspec.info/features/7-1/rspec-rails/job-specs/job-spec
278
+ [view]: https://rspec.info/features/7-1/rspec-rails/view-specs/view-spec
279
+ [routing]: https://rspec.info/features/7-1/rspec-rails/routing-specs
280
+ [helper]: https://rspec.info/features/7-1/rspec-rails/helper-specs/helper-spec
281
+ [`ActionDispatch::IntegrationTest`]: https://api.rubyonrails.org/classes/ActionDispatch/IntegrationTest.html
282
+ [`ActionDispatch::SystemTestCase`]: https://api.rubyonrails.org/classes/ActionDispatch/SystemTestCase.html
283
+ [`ActionController::TestCase`]: https://api.rubyonrails.org/classes/ActionController/TestCase.html
284
+ [in the appropriate folder]: https://rspec.info/features/7-1/rspec-rails/directory-structure
355
285
 
356
- ```ruby
357
- # rspec-rails-1.x
358
- render
359
- response.should xxx
286
+ ### System specs, feature specs, request specs–what’s the difference?
360
287
 
361
- # rspec-rails-2.x+
362
- render
363
- rendered.should xxx
288
+ RSpec Rails provides some end-to-end (entire application) testing capability
289
+ to specify the interaction with the client.
364
290
 
365
- # rspec-rails-2.x+ with expect syntax
366
- render
367
- expect(rendered).to xxx
368
- ```
291
+ #### System specs
369
292
 
370
- ## Routing specs
293
+ Also called **acceptance tests**, **browser tests**, or **end-to-end tests**,
294
+ system specs test the application from the perspective of a _human client._
295
+ The test code walks through a user’s browser interactions,
371
296
 
372
- Routing specs default to residing in the `spec/routing` folder. Tagging any
373
- context with the metadata `:type => :routing` treats it's examples as routing
374
- specs.
297
+ * `visit '/login'`
298
+ * `fill_in 'Name', with: 'jdoe'`
375
299
 
376
- ```ruby
377
- require 'rails_helper'
378
-
379
- RSpec.describe "routing to profiles", :type => :routing do
380
- it "routes /profile/:username to profile#show for username" do
381
- expect(:get => "/profiles/jsmith").to route_to(
382
- :controller => "profiles",
383
- :action => "show",
384
- :username => "jsmith"
385
- )
386
- end
300
+ and the expectations revolve around page content.
387
301
 
388
- it "does not expose a list of profiles" do
389
- expect(:get => "/profiles").not_to be_routable
390
- end
391
- end
392
- ```
302
+ * `expect(page).to have_text('Welcome')`
393
303
 
394
- ### Upgrade note
304
+ Because system specs are a wrapper around Rails’ built-in `SystemTestCase`,
305
+ they’re only available on Rails 5.1+.
306
+ (Feature specs serve the same purpose, but without this dependency.)
395
307
 
396
- `route_for` from rspec-rails-1.x is gone. Use `route_to` and `be_routable`
397
- instead.
308
+ #### Feature specs
398
309
 
399
- ## Helper specs
310
+ Before Rails introduced system testing facilities,
311
+ feature specs were the only spec type for end-to-end testing.
312
+ While the RSpec team now [officially recommends system specs][] instead,
313
+ feature specs are still fully supported, look basically identical,
314
+ and work on older versions of Rails.
400
315
 
401
- Helper specs default to residing in the `spec/helpers` folder. Tagging any
402
- context with the metadata `:type => :helper` treats it's examples as helper
403
- specs.
316
+ On the other hand, feature specs require non-trivial configuration
317
+ to get some important features working,
318
+ like JavaScript testing or making sure each test runs with a fresh DB state.
319
+ With system specs, this configuration is provided out-of-the-box.
404
320
 
405
- Helper specs mix in ActionView::TestCase::Behavior. A `helper` object is
406
- provided which mixes in the helper module being spec'd, along with
407
- `ApplicationHelper` (if present).
321
+ Like system specs, feature specs require the [Capybara][] gem.
322
+ Rails 5.1+ includes it by default as part of system tests,
323
+ but if you don’t have the luxury of upgrading,
324
+ be sure to add it to the `:test` group of your `Gemfile` first:
408
325
 
409
326
  ```ruby
410
- require 'rails_helper'
411
-
412
- RSpec.describe EventsHelper, :type => :helper do
413
- describe "#link_to_event" do
414
- it "displays the title, and formatted date" do
415
- event = Event.new("Ruby Kaigi", Date.new(2010, 8, 27))
416
- # helper is an instance of ActionView::Base configured with the
417
- # EventsHelper and all of Rails' built-in helpers
418
- expect(helper.link_to_event).to match /Ruby Kaigi, 27 Aug, 2010/
419
- end
420
- end
327
+ group :test do
328
+ gem "capybara"
421
329
  end
422
330
  ```
423
331
 
424
- ## Matchers
425
-
426
- Several domain-specific matchers are provided to each of the example group
427
- types. Most simply delegate to their equivalent Rails' assertions.
428
-
429
- ### `be_a_new`
430
-
431
- - Available in all specs
432
- - Primarily intended for controller specs
433
-
434
- ```ruby
435
- expect(object).to be_a_new(Widget)
436
- ```
437
-
438
- Passes if the object is a `Widget` and returns true for `new_record?`
439
-
440
- ### `render_template`
332
+ [officially recommends system specs]: https://rspec.info/blog/2017/10/rspec-3-7-has-been-released/#rails-actiondispatchsystemtest-integration-system-specs
333
+ [Capybara]: https://github.com/teamcapybara/capybara
441
334
 
442
- - Delegates to Rails' `assert_template`
443
- - Available in request, controller, and view specs
335
+ #### Request specs
444
336
 
445
- In request and controller specs, apply to the `response` object:
337
+ Request specs are for testing the application
338
+ from the perspective of a _machine client._
339
+ They begin with an HTTP request and end with the HTTP response,
340
+ so they’re faster than feature specs,
341
+ but do not examine your app’s UI or JavaScript.
446
342
 
447
- ```ruby
448
- expect(response).to render_template("new")
449
- ```
343
+ Request specs provide a high-level alternative to controller specs.
344
+ In fact, as of RSpec 3.5, both the Rails and RSpec teams
345
+ [discourage directly testing controllers][]
346
+ in favor of functional tests like request specs.
450
347
 
451
- In view specs, apply to the `view` object:
348
+ When writing them, try to answer the question,
349
+ “For a given HTTP request (verb + path + parameters),
350
+ what HTTP response should the application return?”
452
351
 
453
- ```ruby
454
- expect(view).to render_template(:partial => "_form", :locals => { :widget => widget } )
455
- ```
352
+ [discourage directly testing controllers]: https://rspec.info/blog/2016/07/rspec-3-5-has-been-released/#rails-support-for-rails-5
456
353
 
457
- ### `redirect_to`
354
+ ## Contributing
458
355
 
459
- - Delegates to `assert_redirect`
460
- - Available in request and controller specs
461
-
462
- ```ruby
463
- expect(response).to redirect_to(widgets_path)
464
- ```
465
-
466
- ### `route_to`
467
-
468
- - Delegates to Rails' `assert_routing`
469
- - Available in routing and controller specs
470
-
471
- ```ruby
472
- expect(:get => "/widgets").to route_to(:controller => "widgets", :action => "index")
473
- ```
474
-
475
- ### `be_routable`
476
-
477
- Passes if the path is recognized by Rails' routing. This is primarily intended
478
- to be used with `not_to` to specify standard CRUD routes which should not be
479
- routable.
480
-
481
- ```ruby
482
- expect(:get => "/widgets/1/edit").not_to be_routable
483
- ```
484
-
485
- ### `have_http_status`
486
-
487
- - Passes if `response` has a matching HTTP status code
488
- - The following symbolic status codes are allowed:
489
- - `Rack::Utils::SYMBOL_TO_STATUS_CODE`
490
- - One of the defined `ActionDispatch::TestResponse` aliases:
491
- - `:error`
492
- - `:missing`
493
- - `:redirect`
494
- - `:success`
495
- - Available in controller, feature, and request specs.
496
-
497
- In controller and request specs, apply to the `response` object:
498
-
499
- ```ruby
500
- expect(response).to have_http_status(201)
501
- expect(response).not_to have_http_status(:created)
502
- ```
503
-
504
- In feature specs, apply to the `page` object:
505
-
506
- ```ruby
507
- expect(page).to have_http_status(:success)
508
- ```
509
-
510
- ## `rake` tasks
511
-
512
- Several rake tasks are provided as a convience for working with RSpec. To run
513
- the entire spec suite use `rake spec`. To run a subset of specs use the
514
- associated type task, for example `rake spec:models`.
515
-
516
- A full list of the available rake tasks can be seen by running `rake -T | grep
517
- spec`.
518
-
519
- ### Customizing `rake` tasks
520
-
521
- If you want to customize the behavior of `rake spec`, you may [define your own
522
- task in the `Rakefile` for your
523
- project](https://www.relishapp.com/rspec/rspec-core/docs/command-line/rake-task).
524
- However, you must first clear the task that rspec-rails defined:
525
-
526
- ```ruby
527
- task("spec").clear
528
- ```
356
+ - [Build details](BUILD_DETAIL.md)
357
+ - [Code of Conduct](CODE_OF_CONDUCT.md)
358
+ - [Detailed contributing guide](CONTRIBUTING.md)
529
359
 
530
- ## Contribute
360
+ Once you’ve cloned the repo and [set up the environment](DEVELOPMENT.md),
361
+ you can run the specs and Cucumber features, or submit a pull request.
531
362
 
532
- See [http://github.com/rspec/rspec-dev](http://github.com/rspec/rspec-dev).
363
+ ## See Also
533
364
 
534
- For `rspec-rails`-specific development information, see
535
- [README_DEV](https://github.com/rspec/rspec-rails/blob/master/README_DEV.md).
365
+ ### RSpec base libraries
536
366
 
537
- ## Also see
367
+ * https://github.com/rspec/rspec
368
+ * https://github.com/rspec/rspec-core
369
+ * https://github.com/rspec/rspec-expectations
370
+ * https://github.com/rspec/rspec-mocks
538
371
 
539
- * [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
540
- * [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core)
541
- * [http://github.com/rspec/rspec-expectations](http://github.com/rspec/rspec-expectations)
542
- * [http://github.com/rspec/rspec-mocks](http://github.com/rspec/rspec-mocks)
372
+ ### Recommended third-party extensions
543
373
 
544
- ## Feature Requests & Bugs
374
+ * [FactoryBot](https://github.com/thoughtbot/factory_bot)
375
+ * [Capybara](https://github.com/teamcapybara/capybara)
376
+ (Included by default in Rails 5.1+.
377
+ Note that [additional configuration is required][] to use the Capybara DSL
378
+ anywhere other than system specs and feature specs.)
545
379
 
546
- See <http://github.com/rspec/rspec-rails/issues>
380
+ [additional configuration is required]: https://rubydoc.info/gems/rspec-rails/file/Capybara.md