rspec-rails 2.14.2 → 4.1.2

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