effective_test_bot 0.4.11 → 0.4.12
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ede27ddd554e49edc914d193530a5d0d90b1334
|
4
|
+
data.tar.gz: 30ad17c211358cf211bd583d58044a44ec4a8946
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13471d53e1e4cf34d78dae3b4802567c862c2eb93517b0503926fc367e7b42e3b7e9c1785ef5e74abb989e95facaccaa6846e7778db43717ac3a2e354566f7d4
|
7
|
+
data.tar.gz: 1d9b51c137546d51ef794dd2ed9e984e7fcc5bbba5e45c57882be783cf006f3dee0519450ca10c6be5d1f984e1496d1ae31c856a32a68285ec51c4bc3fdbacbe
|
data/README.md
CHANGED
@@ -2,27 +2,23 @@
|
|
2
2
|
|
3
3
|
Stop testing and start test botting.
|
4
4
|
|
5
|
-
A minitest library of capybara
|
5
|
+
A [minitest](https://github.com/seattlerb/minitest) library of [capybara](https://github.com/jnicklas/capybara) based feature tests that should pass in every Ruby on Rails application.
|
6
6
|
|
7
|
-
Adds many additional
|
7
|
+
Adds many additional assertions and quality of life helper functions.
|
8
8
|
|
9
|
-
Provides a curated set of minitest
|
9
|
+
Provides a curated set of minitest and capybara focused rails testing gems and a well configured `test_helper.rb` file.
|
10
10
|
|
11
|
-
|
11
|
+
Run `rake test:bot:environment` to validate your testing environment. Ensures that all fixtures and seeds are properly initialized. Makes sure database transactions and web sessions correctly reset between tests.
|
12
12
|
|
13
|
-
|
13
|
+
Adds many class and instance level 1-liners to run entire test suites and check many assertions all at once.
|
14
14
|
|
15
|
-
|
15
|
+
Autosaves an animated .gif for any failing test.
|
16
16
|
|
17
|
-
|
17
|
+
Run `rake test:bot` to automatically check every route in your application against an appropriate test suite, without writing any code. Clicks through every page, intelligently fills forms with appropriate pseudo-random input and checks for all kinds of errors and omissions.
|
18
18
|
|
19
|
-
|
19
|
+
Turn on tour mode to programatically generate an animated .gif of every workflow in your website.
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
Turn on tour mode to automatically generate animated gifs of every part of your website.
|
24
|
-
|
25
|
-
Makes sure everything actually works.
|
21
|
+
Make sure everything actually works.
|
26
22
|
|
27
23
|
## Getting Started
|
28
24
|
|
@@ -50,27 +46,27 @@ end
|
|
50
46
|
|
51
47
|
Run the bundle command to install it:
|
52
48
|
|
53
|
-
```
|
49
|
+
```
|
54
50
|
bundle install
|
55
51
|
```
|
56
52
|
|
57
53
|
Install the configuration file:
|
58
54
|
|
59
|
-
```
|
55
|
+
```
|
60
56
|
rails generate effective_test_bot:install
|
61
57
|
```
|
62
58
|
|
63
|
-
The generator will run `minitest:install` if
|
59
|
+
The generator will run `minitest:install` if not already present and create an initializer file which describes all config options.
|
64
60
|
|
65
|
-
Fixture or seed one user
|
61
|
+
Fixture or seed one user. At least one user -- ideally a fully priviledged admin type user -- must be created.
|
66
62
|
|
67
|
-
|
63
|
+
(there are future plans to make this better. Right now `rake test:bot` just runs everything as one user. There really isn't support for 'this user should not be able to' yet.)
|
68
64
|
|
69
|
-
|
65
|
+
To create the initial user, please add it to either `test/fixtures/users.yml`, the `db/seeds.db` file or the effective_test_bot specific `test/fixtures/seeds.rb` file.
|
70
66
|
|
71
|
-
As per the `test/test_helper.rb
|
67
|
+
As per the included `test/test_helper.rb`, the following tasks run when minitest starts:
|
72
68
|
|
73
|
-
```
|
69
|
+
```
|
74
70
|
# Rails default task, load fixtures from test/fixtures/*.yml (including users.yml if it exists)
|
75
71
|
rake db:fixtures:load
|
76
72
|
|
@@ -83,66 +79,66 @@ rake test:load_fixture_seeds
|
|
83
79
|
|
84
80
|
Your initial user may be created by any of the above 3 tasks.
|
85
81
|
|
86
|
-
|
87
|
-
|
88
|
-
Run `rake test:bot:environment` and make sure all the tests pass.
|
82
|
+
Finally, to test that your testing environment is set up correctly run `rake test:bot:environment` and have all tests pass.
|
89
83
|
|
90
84
|
You now have effective_test_bot configured and you're ready to go.
|
91
85
|
|
92
86
|
# How to use this gem
|
93
87
|
|
94
|
-
Effective TestBot
|
88
|
+
Effective TestBot provides 4 areas of support in writing [minitest](https://github.com/seattlerb/minitest) [capybara](https://github.com/jnicklas/capybara) tests. As a developer, use this gem to:
|
89
|
+
|
90
|
+
1.) Enjoy a whole bunch of individual assertions and quality of life helper functions.
|
95
91
|
|
96
|
-
|
92
|
+
2.) Call one-liner methods to run test suites (10-50+ assertions) against a page, or use these methods to build larger tests.
|
97
93
|
|
98
|
-
|
94
|
+
3.) Produce animated .gifs of test runs. Enable autosave_animated_gif_on_failure to help debug a tricky test, or run in tour mode and record walkthroughs of features.
|
99
95
|
|
100
|
-
|
96
|
+
4.) Apply full stack automated testing. Just run `rake test:bot` to scan every route in your application and without writing any code check every controller action with an appropriate test suite.
|
101
97
|
|
102
98
|
## Minitest Assertions
|
103
99
|
|
104
|
-
The following assertions are added for use in any
|
100
|
+
The following assertions are added for use in any integration test:
|
105
101
|
|
106
|
-
- `assert_signed_in` visits the devise `new_user_session_path` and checks for the
|
107
|
-
- `assert_signed_out` visits the devise `new_user_session_path` and checks for
|
108
|
-
- `assert_page_title` makes sure there is an html
|
109
|
-
- `assert_submit_input` makes sure there is an input[type='submit'] present
|
102
|
+
- `assert_signed_in` visits the devise `new_user_session_path` and checks for the already signed in content.
|
103
|
+
- `assert_signed_out` visits the devise `new_user_session_path` and checks for the sign in content.
|
104
|
+
- `assert_page_title` makes sure there is an html `<title></title>` present.
|
105
|
+
- `assert_submit_input` makes sure there is an `input[type='submit']` present.
|
110
106
|
- `assert_page_status` checks for a given http status, default 200.
|
111
|
-
- `assert_current_path(path)` asserts the current page path
|
112
|
-
- `assert_redirect(from_path)` optionally with to_path, makes sure the current page path is not from_path
|
113
|
-
- `assert_no_js_errors` - checks for any javascript errors on the page
|
107
|
+
- `assert_current_path(path)` asserts the current page path.
|
108
|
+
- `assert_redirect(from_path)` optionally with to_path, makes sure the current page path is not from_path.
|
109
|
+
- `assert_no_js_errors` - checks for any javascript errors on the page.
|
114
110
|
- `assert_no_unpermitted_params` makes sure the last submitted form did not include any unpermitted params and prints out any unpermitted params that do exist.
|
115
|
-
- `assert_no_exceptions` checks for any exceptions in the last page request and gives a stacktrace if there was
|
116
|
-
- `assert_no_html_form_validation_errors` checks for frontend html5 errors
|
117
|
-
- `assert_jquery_ujs_disable_with` makes sure all input[type=submit] elements on the page have the data-disable-with property set
|
118
|
-
- `assert_flash
|
119
|
-
- `assert_assigns` asserts a given rails view_assigns object is present
|
120
|
-
- `assert_no_assigns_errors`
|
111
|
+
- `assert_no_exceptions` checks for any exceptions in the last page request and gives a stacktrace if there was.
|
112
|
+
- `assert_no_html_form_validation_errors` checks for frontend html5 errors.
|
113
|
+
- `assert_jquery_ujs_disable_with` makes sure all `input[type=submit]` elements on the page have the `data-disable-with` property set.
|
114
|
+
- `assert_flash`, optionally with the desired `:success`, `:error` key and/or message, makes sure the flash is set.
|
115
|
+
- `assert_assigns` asserts a given rails view_assigns object is present.
|
116
|
+
- `assert_no_assigns_errors` should be used after any form submit to make sure your assigned rails object has no errors. Prints out any errors if they exist.
|
121
117
|
- `assert_assigns_errors` use after an intentionally invalid form submit to make sure your assigned rails object has errors, or a specific error.
|
122
118
|
|
119
|
+
As well,
|
120
|
+
|
121
|
+
- `assert_page_normal` checks for general errors on the current page. Checks include `assert_no_exceptions`, `assert_page_status`, `assert_no_js_errors`, and `assert_page_title`.
|
122
|
+
|
123
123
|
## Capybara Extras
|
124
124
|
|
125
|
-
The following quality of life helpers are added
|
125
|
+
The following quality of life helpers are added by this gem:
|
126
126
|
|
127
127
|
### fill_form
|
128
128
|
|
129
|
-
Finds all
|
129
|
+
Finds all input, select and textarea form fields and fills them with pseudo-random but appropriate values.
|
130
130
|
|
131
|
-
|
131
|
+
Intelligently fills names, addresses, start and end dates, telephone numbers, postal and zip codes, file, price, email, numeric, password and password confirmation fields. Probably more.
|
132
132
|
|
133
133
|
Will only fill visible fields that are currently visible and not disabled.
|
134
134
|
|
135
135
|
If a selection made in one field changes the visibility/disabled of fields later in the form, those fields will be properly filled.
|
136
136
|
|
137
|
-
It
|
138
|
-
|
139
|
-
It will click through bootstrap tabs and fill them left-to-right one tab at a time.
|
137
|
+
It clicks through bootstrap tabs and fill them nicely left-to-right, one tab at a time, and knows how to work with [cocoon](https://github.com/nathanvda/cocoon), [select2](https://select2.github.io/) and [effective_assets](https://github.com/code-and-effect/effective_assets) form fields.
|
140
138
|
|
141
139
|
You can pass a Hash of 'fills' to specify specific input values:
|
142
140
|
|
143
141
|
```ruby
|
144
|
-
require 'test_helper'
|
145
|
-
|
146
142
|
class PostTest < ActionDispatch::IntegrationTest
|
147
143
|
test 'creating a new post' do
|
148
144
|
visit new_post_path
|
@@ -166,156 +162,409 @@ The `min` and `max` html properties are considered when filling in any numeric f
|
|
166
162
|
|
167
163
|
If there are 2 or more numeric inputs that end with the same jquery selector, the fields will be filled so that their sum will match the html `max` value.
|
168
164
|
|
169
|
-
You can scope the fill_form to a particular area of the page by using the regular
|
165
|
+
You can scope the fill_form to a particular area of the page by using the regular `within` `do..end` block
|
170
166
|
|
171
167
|
### submit_form
|
172
168
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
169
|
+
Clicks the first `input[type='submit']` field (or first submit field with the given label) and submits the form.
|
170
|
+
|
171
|
+
Automatically checks for `assert_no_html5_form_validation_errors`, `assert_jquery_ujs_disable_with` and `assert_no_unpermitted_params`
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
class PostTest < ActionDispatch::IntegrationTest
|
175
|
+
test 'creating a new post' do
|
176
|
+
visit(new_post_path) and fill_form
|
177
|
+
submit_form # or submit_form('Save and Continue')
|
178
|
+
end
|
179
|
+
end
|
180
|
+
```
|
177
181
|
|
178
182
|
### other helpers
|
179
183
|
|
180
|
-
- `submit_novalidate_form`
|
184
|
+
- `submit_novalidate_form` submits the form without client side validation, ignoring any required field requirements.
|
181
185
|
- `clear_form` clears all form fields, probably used before `submit_novalidate_form` to test invalid form submissions.
|
182
186
|
- `sign_in(user)` optionally with user, signs in via `Warden::Test::Helpers` hacky login skipping method.
|
183
|
-
- `sign_in_manually(user, password)` visits the devise `new_user_session_path` and signs in via the form
|
187
|
+
- `sign_in_manually(user, password)` visits the devise `new_user_session_path` and signs in via the form.
|
184
188
|
- `sign_up` visits the devise `new_user_registration_path` and signs up as a new user.
|
185
|
-
- `as_user(user) do .. end` yields a block between `sign_in`, and `logout
|
186
|
-
- `synchronize!` should fix any timing issues waiting for
|
189
|
+
- `as_user(user) do .. end` yields a block between `sign_in`, and `logout`.
|
190
|
+
- `synchronize!` should fix any timing issues waiting for page elements.
|
187
191
|
- `was_redirect?` returns true/false if the last time we changed pages was a 304 redirect.
|
188
192
|
- `was_download?` if clicking a link returned a file of any type rather than a page change.
|
189
193
|
|
190
194
|
## Capybara Super Extras
|
191
195
|
|
192
|
-
|
196
|
+
Running integration tests with [capybara-webkit](https://github.com/thoughtbot/capybara-webkit) is truly a black-box integration testing experience. This provides a lot of benefits, but also some severe limitations.
|
193
197
|
|
194
|
-
|
198
|
+
The test web server runs in a totally separate process. It knows nothing about your application and it does not have access to any of the rails internal state. It only sees html, javascript, css and urls.
|
195
199
|
|
196
|
-
effective_test_bot
|
200
|
+
effective_test_bot fills in this knowledge gap by serializing any interesting values within the http header. This gives our tests a way to peek inside the black box.
|
197
201
|
|
198
|
-
The following
|
202
|
+
The following representations of the rails internal state are made available:
|
199
203
|
|
200
|
-
- `
|
201
|
-
- `assigns` a Hash representation of the current page's rails `view_assigns`. Serializes any ActiveRecord objects, as well as any TrueClass, FalseClass, NilClass, String, Symbol, Numeric objects. Does not serialize anything else, but sets a symbol `assigns[key] == :present_but_not_serialized`.
|
204
|
+
- `assigns` a Hash representation of the current page's rails `view_assigns`. Serializes any `ActiveRecord` objects, as well as any `TrueClass`, `FalseClass`, `NilClass`, `String`, `Symbol`, and `Numeric` objects. Does not serialize anything else, but sets a symbol `assigns[key] == :present_but_not_serialized`.
|
202
205
|
- `exceptions` an Array with the exception message and a stacktrace.
|
203
|
-
- `
|
206
|
+
- `flash` a Hash representation of the current page's flash.
|
207
|
+
- `unpermitted_params` an Array of any unpermitted parameters that were encountered by the last request.
|
208
|
+
|
209
|
+
## Effective Test Suites
|
210
|
+
|
211
|
+
Each of the following test suites make 10-50+ assertions on a given page or controller action. The idea is to check for every possible error or omission accross all layers of the stack.
|
212
|
+
|
213
|
+
These may be used as standalone one-liners, in the style of [shoulda-matchers](https://github.com/thoughtbot/shoulda-matchers) and as helper methods to quickly build up more advanced tests.
|
214
|
+
|
215
|
+
Each test suite has a class-level one-liner `x_test` and and one or more instance level `x_action_test` versions.
|
216
|
+
|
217
|
+
### crud_test
|
218
|
+
|
219
|
+
This test runs through the standard [CRUD](http://edgeguides.rubyonrails.org/getting_started.html) workflow of a given controller and checks that resource creation functions as expected -- that all the model, controller, views and database actually work -- and tries to enforce best practices.
|
220
|
+
|
221
|
+
There are 9 different `crud_action_test` test suites that may be run individually. The one-liner `crud_test` runs all of them.
|
222
|
+
|
223
|
+
The following instance level `crud_action_test` methods are available:
|
224
|
+
|
225
|
+
- `crud_action_test(:index)` signs in as the given user, finds or creates a resource, visits `resources_path` and checks that a collection of resources has been assigned.
|
226
|
+
- `crud_action_test(:new)` signs in as the given user, visits `new_resource_path`, and checks for a properly named form appropriate to the resource.
|
227
|
+
- `crud_action_test(:create_invalid)` signs in as the given user, visits `new_resource_path` and submits an empty form. Checks that all errors are properly assigned and makes sure a new resource was not created.
|
228
|
+
- `crud_action_test(:create_valid)` signs in as the given user, visits `new_resource_path`, and submits a valid form. Checks for any errors and makes sure a new resource was created.
|
229
|
+
- `crud_action_test(:show)` signs in as the given user, finds or creates a resource, visits `resource_path` and checks that the resource is shown.
|
230
|
+
- `crud_action_test(:edit)` signs in as the given user, finds or creates a resource, visits `edit_resource_path` and checks that an appropriate form exists for this resource.
|
231
|
+
- `crud_action_test(:update_invalid)` signs in as the given user, finds or creates a resource, visits `edit_resource_path` and submits an empty form. Checks that the existing resource wasn't updated and that all errors are properly assigned and displayed.
|
232
|
+
- `crud_action_test(:update_valid)` signs in as the given user, finds or creates a resource, visits `edit_resource_path` and submits a valid form. Checks for any errors and makes sure the existing resource was updated.
|
233
|
+
- `crud_action_test(:destroy)` signs in as the given user, finds or creates a resource, visits `resources_path`. It then finds or creates a link to destroy the resource and clicks the link. Checks for any errors and makes sure the resource was deleted. If the resource `respond_to?(:archived)` it will check for archive behavior instead of delete.
|
234
|
+
|
235
|
+
Also,
|
236
|
+
|
237
|
+
- `crud_action_test(:tour)` signs in as a given user and calls all the above `crud_action_test` methods from inside one test. The animated .gif produced from this test suite records the entire process of creating, showing, editing and deleting a resource from start to finish. It makes all the same assertions as running the test suites individually.
|
238
|
+
|
239
|
+
|
240
|
+
A quick note on speed: You can speed up these test suites by fixturing, seeding or first creating an instance of the resource being tested. Any tests that need to `find_or_create_resource` check for an existing resource first, otherwise visit `new_resource_path` and submit a form to create the resource. Having a resource already created will speed things up.
|
241
|
+
|
242
|
+
There are a few variations on the one-liner method:
|
243
|
+
|
244
|
+
```ruby
|
245
|
+
class PostsTest < ActionDispatch::IntegrationTest
|
246
|
+
# Runs all 9 crud_action tests against /posts
|
247
|
+
crud_test(Post, User.first)
|
248
|
+
|
249
|
+
# Runs all 9 crud_action tests against /posts and use this Post's attributes when calling fill_form.
|
250
|
+
crud_test(Post.new(title: 'my first post'), User.first)
|
251
|
+
|
252
|
+
# Runs all 9 crud_action tests against /admin/posts controller as a previously seeded or fixtured admin user
|
253
|
+
crud_test('admin/posts', User.where(admin: true).first)
|
254
|
+
|
255
|
+
# Run only some tests
|
256
|
+
crud_test(Post, User.first, only: [:new, :create_valid, :create_invalid, :show, :index])
|
257
|
+
|
258
|
+
# Run all except some tests
|
259
|
+
crud_test(Post, User.first, except: [:edit, :update_valid, :update_invalid])
|
204
260
|
|
205
|
-
|
261
|
+
# Skip individual assertions
|
262
|
+
crud_test(Post, User.first, skip: {create_valid: :path, update_invalid: [:path, :flash]})
|
263
|
+
end
|
264
|
+
```
|
265
|
+
|
266
|
+
The individual test suites may also be used as part of a larger test:
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
class PostsTest < ActionDispatch::IntegrationTest
|
270
|
+
test 'user may only update a post once' do
|
271
|
+
crud_action_test(:create_valid, Post, User.first)
|
272
|
+
assert_content 'successfully created post. You may only update it once.'
|
273
|
+
|
274
|
+
crud_action_test(:update_valid, Post.last, User.first)
|
275
|
+
assert_content 'successfully updated post.'
|
276
|
+
|
277
|
+
crud_action_test(:update_valid, Post.last, User.first, skip: [:no_assigns_errors, :updated_at])
|
278
|
+
assert_assigns_errors(:post, 'you may no longer update this post.')
|
279
|
+
assert_content 'you may no longer update this post.'
|
280
|
+
end
|
281
|
+
end
|
282
|
+
```
|
283
|
+
|
284
|
+
If your resource controller passes a `crud_test` you can be certain that your user is able to correctly create, edit, display and delete a resource without encountering any application errors.
|
285
|
+
|
286
|
+
### devise_test
|
287
|
+
|
288
|
+
This test runs through the the [devise](https://github.com/plataformatec/devise) sign up, sign in, and sign in invalid workflows.
|
289
|
+
|
290
|
+
- `devise_action_test(:sign_up)` visits the devise `new_user_registration_path`, submits the sign up form and validates the `current_user`.
|
291
|
+
- `devise_action_test(:sign_in)` creates a new user and makes sure the sign in process works.
|
292
|
+
- `devise_action_test(:sign_in_invalid)` makes sure an invalid password is correctly denied.
|
293
|
+
|
294
|
+
Use as a one-liner:
|
295
|
+
|
296
|
+
```ruby
|
297
|
+
class MyApplicationTest < ActionDispatch::IntegrationTest
|
298
|
+
devise_test # Runs all tests (sign_up, sign_in_valid, and sign_in_invalid)
|
299
|
+
end
|
300
|
+
```
|
206
301
|
|
207
|
-
|
302
|
+
Or each individually in part of a regular test:
|
208
303
|
|
209
|
-
|
304
|
+
```ruby
|
305
|
+
class MyApplicationTest < ActionDispatch::IntegrationTest
|
306
|
+
test 'user receives 10 tokens after signing up' do
|
307
|
+
devise_action_test(:sign_up)
|
308
|
+
assert_content 'Tokens: 10'
|
309
|
+
assert_equals 10, User.last.tokens
|
310
|
+
assert_equals 10, assigns(:current_user).tokens
|
311
|
+
end
|
312
|
+
end
|
313
|
+
```
|
314
|
+
|
315
|
+
### member_test
|
316
|
+
|
317
|
+
This test is intended for non-CRUD actions that operate on a specific instance of a resource.
|
318
|
+
|
319
|
+
The action must be a `GET` with a required `id` value. `member_test`-able actions appear as follows from `rake routes`:
|
320
|
+
|
321
|
+
```
|
322
|
+
unarchive_post GET /posts/:id/unarchive(.:format) posts#unarchive
|
323
|
+
```
|
210
324
|
|
211
|
-
|
325
|
+
This test signs in as the given user, visits the given controller/action/page and checks `assert_page_normal` and `assert_assigns`.
|
212
326
|
|
213
|
-
|
327
|
+
Use it as a one-liner:
|
214
328
|
|
215
329
|
```ruby
|
216
|
-
|
330
|
+
class PostsTest < ActionDispatch::IntegrationTest
|
331
|
+
# Uses find_or_create_resource! to load a seeded resource or create a new one
|
332
|
+
member_test('posts', 'unarchive', User.first)
|
333
|
+
|
334
|
+
# Run the member_test with a specific post
|
335
|
+
member_test('posts', 'unarchive', User.first, Post.find(1))
|
336
|
+
end
|
337
|
+
```
|
338
|
+
|
339
|
+
Or as part of a regular test:
|
217
340
|
|
341
|
+
```ruby
|
218
342
|
class PostsTest < ActionDispatch::IntegrationTest
|
219
|
-
|
343
|
+
test 'posts can be unarchived' do
|
344
|
+
post = Post.create(title: 'first post', archived: true)
|
345
|
+
|
346
|
+
assert Post.where(archived: false).empty?
|
347
|
+
member_action_test('posts', 'unarchive', User.first, post)
|
348
|
+
assert Post.where(archived: false).present?
|
349
|
+
end
|
350
|
+
end
|
351
|
+
```
|
352
|
+
|
353
|
+
### page_test
|
354
|
+
|
355
|
+
This test signs in as the given user, visits the given page and simply checks `assert_page_normal`.
|
356
|
+
|
357
|
+
Use it as a one-liner:
|
358
|
+
|
359
|
+
```ruby
|
360
|
+
class PostsTest < ActionDispatch::IntegrationTest
|
361
|
+
page_test(:posts_path, User.first) # Runs the page_test test suite against posts_path as User.first
|
362
|
+
end
|
363
|
+
```
|
364
|
+
|
365
|
+
Or as part of a regular test:
|
366
|
+
|
367
|
+
```ruby
|
368
|
+
class PostsTest < ActionDispatch::IntegrationTest
|
369
|
+
test 'posts are displayed on the index page' do
|
370
|
+
Post.create(title: 'first post')
|
220
371
|
|
221
|
-
# Does the same thing.
|
222
|
-
# Runs the page_test suite against posts_path (instance level) as User.first
|
223
|
-
test 'my posts test' do
|
224
372
|
page_action_test(:posts_path, User.first)
|
373
|
+
|
374
|
+
assert page.current_path, '/posts'
|
375
|
+
assert_content 'first post'
|
376
|
+
end
|
377
|
+
end
|
378
|
+
```
|
379
|
+
|
380
|
+
### redirect_test
|
381
|
+
|
382
|
+
This test signs in as the given user, visits the given page then checks `assert_redirect(from_path, to_path)` and `assert_page_normal`.
|
383
|
+
|
384
|
+
Use it as a one-liner:
|
385
|
+
|
386
|
+
```ruby
|
387
|
+
class PostsTest < ActionDispatch::IntegrationTest
|
388
|
+
# Visits /blog and tests that it redirects to a working /posts page
|
389
|
+
redirect_test('/blog', '/posts', User.first)
|
390
|
+
end
|
391
|
+
```
|
392
|
+
|
393
|
+
Or as part of a regular test:
|
394
|
+
|
395
|
+
```ruby
|
396
|
+
class PostsTest < ActionDispatch::IntegrationTest
|
397
|
+
test 'visiting blog redirects to posts' do
|
398
|
+
Post.create(title: 'first post')
|
399
|
+
redirect_action_test('/blog', '/posts', User.first)
|
400
|
+
assert_content 'first post'
|
225
401
|
end
|
226
402
|
end
|
227
403
|
```
|
228
404
|
|
229
|
-
###
|
405
|
+
### wizard_test
|
406
|
+
|
407
|
+
This test signs in as the given user, visits the given initial page and continually runs `fill_form`, `submit_form` and `assert_page_normal` up until the given final page, or until no more `input[type=submit]` are present.
|
230
408
|
|
231
|
-
|
409
|
+
It tests any number of steps in a wizard, multi-step form, or inter-connected series of pages.
|
232
410
|
|
233
|
-
|
411
|
+
As well, in the `wizard_action_test`, each page is yielded to the calling method.
|
234
412
|
|
235
|
-
|
413
|
+
Use it as a one-liner:
|
236
414
|
|
237
|
-
```
|
415
|
+
```ruby
|
416
|
+
class PostsTest < ActionDispatch::IntegrationTest
|
417
|
+
wizard_test('/build_post/step1', '/build_post/step5', User.first)
|
418
|
+
end
|
419
|
+
```
|
420
|
+
|
421
|
+
Or as part of a regular test:
|
422
|
+
|
423
|
+
```ruby
|
424
|
+
class PostsTest < ActionDispatch::IntegrationTest
|
425
|
+
test 'building a post in 5 steps' do
|
426
|
+
wizard_action_test('/build_post/step1', '/build_post/step5', User.first) do
|
427
|
+
if page.current_path.end_with?('step4')
|
428
|
+
assert_content 'your post is ready but must first be approved by an admin.'
|
429
|
+
end
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
```
|
434
|
+
|
435
|
+
## Skipping individual assertions or test suites
|
436
|
+
|
437
|
+
Each of the test suites checks a page or pages for some expected behaviour. Sometimes a developer has a good reason for deviating from what is expected and it's frustrating when just one assertion in a test suite fails.
|
438
|
+
|
439
|
+
So, almost every individual assertion made by these test suites is skippable.
|
440
|
+
|
441
|
+
When an assertion fails, the output will look something like:
|
442
|
+
|
443
|
+
```
|
238
444
|
crud_test: (users#update_invalid) FAIL (3.74s)
|
239
445
|
|
240
|
-
Minitest::Assertion: (
|
241
|
-
Expected: "/users/
|
242
|
-
Actual: "/members/
|
446
|
+
Minitest::Assertion: (current_path) Expected current_path to match resource #update path.
|
447
|
+
Expected: "/users/1"
|
448
|
+
Actual: "/members/1"
|
243
449
|
/Users/matt/Sites/effective_test_bot/test/test_botable/crud_test.rb:155:in `test_bot_update_invalid_test'
|
244
450
|
```
|
245
451
|
|
246
|
-
|
452
|
+
Here, the `(current_path)` is the name of the specific test bot assertion that failed.
|
247
453
|
|
248
|
-
The expectation is that when submitting an invalid form at `/users/
|
454
|
+
The expectation is that when submitting an invalid form at `/users/1/edit` we should be returned to the update action url `/users/1`, but in this totally reasonable but not-standard case we are redirected to `/members/1` instead.
|
249
455
|
|
250
|
-
You can skip this
|
456
|
+
You can skip this assertion by adding it to the `app/config/initializers/effective_test_bot.rb` file:
|
251
457
|
|
252
458
|
```ruby
|
253
459
|
EffectiveTestBot.setup do |config|
|
254
460
|
config.except = [
|
255
|
-
'users#create_invalid
|
256
|
-
'
|
461
|
+
'users#create_invalid current_path', # Skips the current_path assertion for just the users#create_invalid test
|
462
|
+
'current_path', # Skips the current_path assertion entirely in all tests
|
463
|
+
'users#create_invalid' # Skips the entire users#create_invalid test
|
257
464
|
]
|
258
465
|
end
|
259
466
|
```
|
260
467
|
|
261
|
-
There is support for skipping individual assertions
|
468
|
+
There is support for skipping individual assertions, entire tests, or a combination of both.
|
262
469
|
|
263
|
-
Please see the installed effective_test_bot.rb initializer file for a full description of all options.
|
470
|
+
Please see the installed `effective_test_bot.rb` initializer file for a full description of all options.
|
264
471
|
|
265
|
-
|
472
|
+
## Testing the test environment
|
266
473
|
|
267
|
-
|
474
|
+
Unfortunately, with the current day ruby on rails ecosystem, simply getting a testing environment setup correctly is a non-trivial endeavor filled with gotchas and many things that can go wrong.
|
268
475
|
|
269
|
-
|
476
|
+
User sessions need to properly reset and database transactions must be correctly rolled back between tests. Seeds and fixtures that were once valid may become invalid as the application changes. Database migrations must stay up to date. Capybara needs to query your app with a single shared connection or weird things start happening.
|
270
477
|
|
271
|
-
|
478
|
+
Included with this gem is the `rails generate effective_test_bot:install` that does its best to provide a known-good set of configuration files that initialize all required testing gems. However, every developer's machine is different, and there are just too many points of failure. Everyone's `test/test_helper.rb` will be slightly different.
|
272
479
|
|
273
|
-
|
480
|
+
Run `rake test:bot:environment` to check that capybara is doing the right thing, everything is reset properly between test runs, an initial user record exists, all seeded and fixtured data is valid, devise works and rails' jquery-ujs is present.
|
274
481
|
|
275
|
-
|
482
|
+
If all environment tests pass, you will have a great experience with automated testing.
|
276
483
|
|
277
|
-
|
484
|
+
## Automated full stack testing
|
278
485
|
|
279
|
-
|
486
|
+
One of the main goals of `effective_test_bot` is to increase the speed at which tests can be written in any ruby on rails application. Well, there's no faster way of writing tests than by not writing them at all.
|
280
487
|
|
281
|
-
|
282
|
-
|
283
|
-
TODO
|
488
|
+
Run `rake test:bot` to scan every route defined in `routes.rb` and run an appropriate test suite.
|
284
489
|
|
285
|
-
|
490
|
+
You can configure test bot to skip individual tests or assertions, tweak screenshot behaviour and toggle tour mode via the `config/initializers/effective_test_bot.rb` file. As well, there are a few command line options available.
|
286
491
|
|
287
|
-
|
492
|
+
These are some quick ways to customize test bot's behaviour:
|
288
493
|
|
289
|
-
|
290
|
-
|
291
|
-
```ruby
|
292
|
-
rake test:bot:environment
|
494
|
+
```
|
495
|
+
# Scan every route in the application as per config/initializers/effective_test_bot.rb
|
293
496
|
rake test:bot
|
497
|
+
|
498
|
+
# Test a specific controller (any routes matching posts)
|
294
499
|
rake test:bot TEST=posts
|
500
|
+
|
501
|
+
# Test a specific controller and action
|
295
502
|
rake test:bot TEST=posts#index
|
296
503
|
```
|
297
504
|
|
298
|
-
|
505
|
+
## Animated gifs and screenshots
|
506
|
+
|
507
|
+
Call `save_test_bot_screenshot` from within any test to take a screenshot of the current page. If an animated .gif is produced at the end of the test -- either from autosave_animated_gif_on_failure or tour mode -- this screenshot will be used as one of the frames in the animation.
|
508
|
+
|
509
|
+
This method is already called by `fill_form` and `submit_form`.
|
299
510
|
|
300
|
-
|
511
|
+
To disable taking screenshots entirely set `config.screenshots = false` in the `config/initializers/effective_test_bot.rb` initializer file.
|
301
512
|
|
302
|
-
|
513
|
+
### Autosave on failure
|
514
|
+
|
515
|
+
The `test/test_helper.rb` file that is installed by `effective_test_bot` enables [capybara-screenshot](https://github.com/mattheworiordan/capybara-screenshot)'s `autosave_on_failure` functionality. So whenever a test fails, the current html will be written and a .png screenshot will be saved. This is invaluable for troubleshooting why a test has failed.
|
516
|
+
|
517
|
+
Building on this type of feature, `effective_test_bot` will also autosave an animated gif on failure. This does slow down failing tests and can be disabled.
|
303
518
|
|
304
519
|
### Tour mode
|
305
520
|
|
306
|
-
|
521
|
+
When running in tour mode, an animated .gif image file, a "tour", will be created for all successful tests.
|
522
|
+
|
523
|
+
This feature is slow, increasing the runtime of each test by almost 30%, but it's also really cool.
|
524
|
+
|
525
|
+
You can run test bot in tour mode by setting `config.tour_mode = true` in the `config/initializers/effective_test_bot.rb` file or by running any variation of the following rake tasks:
|
526
|
+
|
527
|
+
```
|
528
|
+
# Run test:bot in tour mode, saving an animated .gif for all successful tests
|
307
529
|
rake test:bot:tour
|
530
|
+
rake test:bot TOUR=true
|
531
|
+
|
532
|
+
# Also prints the animated .gif file path to stdout
|
533
|
+
rake test:bot:tourv
|
534
|
+
rake test:bot TOUR=verbose
|
535
|
+
|
536
|
+
# Makes a whole bunch of extra screenshots when filling out forms
|
537
|
+
rake test:bot TOUR=extreme
|
538
|
+
|
539
|
+
# Runs in tour mode and tests only a specific controller or action
|
308
540
|
rake test:bot:tour TEST=posts
|
309
|
-
rake test:bot:
|
541
|
+
rake test:bot:tour TEST=posts#index
|
310
542
|
```
|
311
543
|
|
312
|
-
|
313
|
-
|
314
|
-
|
544
|
+
To print out the file location of all tour files, run the following:
|
545
|
+
|
546
|
+
```
|
547
|
+
# Prints out all animated .gif file locations
|
548
|
+
rake test:bot:tours
|
549
|
+
|
550
|
+
# Prints out any animated .gif files locations with a file name matching posts
|
551
|
+
rake test:bot:tours TEST=posts
|
552
|
+
```
|
553
|
+
|
554
|
+
To delete all tour and autosave on failure animated .gifs, run the following:
|
555
|
+
|
556
|
+
```
|
557
|
+
# Deletes all tour and failure animated .gifs
|
558
|
+
rake test:bot:purge
|
315
559
|
```
|
316
560
|
|
317
|
-
|
561
|
+
As well, to enable tour mode when running the standard `rake test`:
|
318
562
|
|
563
|
+
```
|
564
|
+
# Runs all regular minitest tests with tour mode enabled
|
565
|
+
rake test:tour
|
566
|
+
rake test:tourv
|
567
|
+
```
|
319
568
|
|
320
569
|
## License
|
321
570
|
|
@@ -5,13 +5,14 @@ if Rails.env.test?
|
|
5
5
|
|
6
6
|
# Exclude the following tests or assertions from being run.
|
7
7
|
# config.except = [
|
8
|
-
# 'widgets'
|
9
|
-
# 'posts#create_invalid'
|
10
|
-
# 'posts#index page_title'
|
8
|
+
# 'widgets',
|
9
|
+
# 'posts#create_invalid',
|
10
|
+
# 'posts#index page_title',
|
11
|
+
# 'posts#update_invalid' => ['page_title', 'current_path'],
|
11
12
|
# 'no_unpermitted_params'
|
12
13
|
# ]
|
13
14
|
|
14
|
-
# Run only the following tests. Doesn't work with individual assertions
|
15
|
+
# Run only the following tests. Doesn't work with individual assertions
|
15
16
|
# config.only = [
|
16
17
|
# 'posts', 'events#index'
|
17
18
|
# ]
|
@@ -110,7 +110,7 @@ module EffectiveTestBotAssertions
|
|
110
110
|
|
111
111
|
# assert_assigns
|
112
112
|
# assert_assigns :current_user
|
113
|
-
# assert_assigns :current_user,
|
113
|
+
# assert_assigns :current_user, 'there should a current user'
|
114
114
|
def assert_assigns(key = nil, value = nil, message = nil)
|
115
115
|
if key.present? && value.present?
|
116
116
|
assert_equal value, assigns[key.to_s], message || "(assigns) Expected assigns[#{key}] to equal #{value}. Instead, it was: #{value}"
|
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
+
# This gets run when we type `rake test:bot`
|
4
|
+
# Scan through every route and run a test suite against it
|
5
|
+
|
3
6
|
module TestBot
|
4
7
|
class ApplicationTest < ActionDispatch::IntegrationTest
|
5
8
|
CRUD_ACTIONS = %w(index create new edit show update destroy) # Same order as resources :object creates them in
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_test_bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|