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: a8b43bf111914f08abc4410da5eadf651d907a3d
4
- data.tar.gz: efbbff64442365fcd0225126a31bb4a4e63aeb9e
3
+ metadata.gz: 5ede27ddd554e49edc914d193530a5d0d90b1334
4
+ data.tar.gz: 30ad17c211358cf211bd583d58044a44ec4a8946
5
5
  SHA512:
6
- metadata.gz: 786cf32fb1a1f4f2560cf63c517aea402240022e4b30bba82171f2704b23659bb6ac9e1aee5895e60f1eb8da33f67a7381dfa6fe5e95665412116378337393ad
7
- data.tar.gz: 2e1af8e474b89eba76a43a01b8bdf6274e1b2faf3e07e2a59cc92529983552cbc6159326093abec4a6f372231365ca6e855abf9f120aeff876bb7f83b6aae800
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-webkit based feature tests that should pass in every Ruby on Rails application.
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 minitest assertions and capybara quality of life helper functions.
7
+ Adds many additional assertions and quality of life helper functions.
8
8
 
9
- Provides a curated set of minitest/capybara/rails testing gems and a well configured `test_helper.rb` minitest file.
9
+ Provides a curated set of minitest and capybara focused rails testing gems and a well configured `test_helper.rb` file.
10
10
 
11
- Includes a rake task to validate your testing environment.
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
- Ensures that all fixtures and seeds are properly initialized. Makes sure database transactions and web sessions correctly reset between tests.
13
+ Adds many class and instance level 1-liners to run entire test suites and check many assertions all at once.
14
14
 
15
- Provides a DSL of class and instance level 1-liners that run entire test suites, checking many assertions all at once.
15
+ Autosaves an animated .gif for any failing test.
16
16
 
17
- Autosaves an animated gif for any failing test.
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
- Run `rake test:bot` to automatically check every route in your application against an appropriate test suite, without writing any code.
19
+ Turn on tour mode to programatically generate an animated .gif of every workflow in your website.
20
20
 
21
- Automatically fills forms with appropriate pseudo-random input, and checks for all kinds of errors and omissions along the way.
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
- ```console
49
+ ```
54
50
  bundle install
55
51
  ```
56
52
 
57
53
  Install the configuration file:
58
54
 
59
- ```console
55
+ ```
60
56
  rails generate effective_test_bot:install
61
57
  ```
62
58
 
63
- The generator will run `minitest:install` if minitest is not already present and create an initializer file which describes all configuration options.
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
- effective_test_bot requires that at least one user -- ideally a fully priviledged admin type user -- be available in the testing environment.
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
- * 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.
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` default file, when minitest and/or effective_test_bot starts, following tasks are run:
67
+ As per the included `test/test_helper.rb`, the following tasks run when minitest starts:
72
68
 
73
- ```ruby
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
- Test that your testing environment is set up correctly:
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 is a 3-layered cake of testing deliciousness.
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
- The bottom layer consists of advanced individual minitest assertions and capybara quality of life helper functions.
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
- The middle layer is a meta testing DSL -- 1-liners for you to use in your regular minitest tests that run entire test suites (10-50+ assertions) against a page or controller.
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
- The final layer builds on the bottom two, run `rake test:bot` to scan every route in your application and choose an appropriate test suite to run.
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 minitest & capybara integration test:
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 `devise.failure.already_authenticated` content
107
- - `assert_signed_out` visits the devise `new_user_session_path` and checks for absense of the `devise.failure.already_authenticated` content
108
- - `assert_page_title` makes sure there is an html <title></title> present
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` optionally with the desired :success, :error key and/or message, makes sure the flash is set
119
- - `assert_assigns` asserts a given rails view_assigns object is present
120
- - `assert_no_assigns_errors` use after a form submit to make sure your assigned rails object has no errors. Prints out any errors if they exist.
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 for use in any minitest & capybara integration test:
125
+ The following quality of life helpers are added by this gem:
126
126
 
127
127
  ### fill_form
128
128
 
129
- Finds all the input, select and textarea form fields on the current page and fills them with pseudo-random appropriate values.
129
+ Finds all input, select and textarea form fields and fills them with pseudo-random but appropriate values.
130
130
 
131
- Detects names, addresses, start and end dates, telephone numbers, postal and zip codes, file, price, email, numeric, password and password confirmation fields. Probably more.
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 works with the [cocoon](https://github.com/nathanvda/cocoon), [select2](https://select2.github.io/) and [effective_assets](https://github.com/code-and-effect/effective_assets) gems.
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 capybara `within` `do..end` block
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
- As well as just click on the `input[type='submit']` button (or optional label), this helper also checks:
174
- - `assert_no_html5_form_validation_errors`
175
- - `assert_jquery_ujs_disable_with`
176
- - `assert_no_unpermitted_params`
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` will use javascript to disable all required fields, and submit a form without client side validation.
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 capybara elements
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
- So the problem with running integration tests with capybara-webkit is that it's a real full black-box integration test.
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
- Capybara runs in a totally separate process. It knows nothing about your rails app. You can't get access to any of the rails internal state. All you can test is html, javascript and urls. That really sucks.
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 mixes in a rails controller include and does a bit of http header hackery to make available to capybara the internal rails state values that are just so handy.
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 are refreshed on each page change, and are available to check anywhere in your tests.
202
+ The following representations of the rails internal state are made available:
199
203
 
200
- - `flash` a Hash representation of the current page's flash
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
- - `unpermitted_params` an Array of any unpermitted paramaters that were encountered by the last request
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
- - `save_test_bot_screenshot` saves a screenshot of the current page to be added to the current test's animated gif (see screenshots and tour mode below).
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
- ## Test Bot DSL Methods
302
+ Or each individually in part of a regular test:
208
303
 
209
- All of the following DSL methods use the assertions and capybara extras to build an entire test suite that runs against a given page or controller action.
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
- Right now the `crud_test` method is by far the most mature, with the other methods having had less development time.
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
- Each DSL method has a class level `x_test` and an instance level `x_action_test` version of each.
327
+ Use it as a one-liner:
214
328
 
215
329
  ```ruby
216
- require 'test_helper'
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
- page_test(:posts_path, User.first) # Runs the page_test test suite against posts_path (class level) as User.first
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
- ### Skipping assertions and tests
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
- Each of these DSL test suite methods are designed to assert an expected standard rails behaviour.
409
+ It tests any number of steps in a wizard, multi-step form, or inter-connected series of pages.
232
410
 
233
- But sometimes a developer has a good reason for deviating from what is considered standard; therefore, each individual assertion is skippable.
411
+ As well, in the `wizard_action_test`, each page is yielded to the calling method.
234
412
 
235
- When an assertion fails, the minitest output will look something like:
413
+ Use it as a one-liner:
236
414
 
237
- ```console
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: (path) Expected current_path to match resource #update path.
241
- Expected: "/users/562391275"
242
- Actual: "/members/562391275"
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
- The `(path)` is the name of the specific assertion that failed.
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/562391275/edit` we should be returned to the update action url `/users/562391275`, but in this totally reasonable but not-standard case we are redirected to `/members/562391275` instead.
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 specific assertion by adding it to the `app/config/initializers/effective_test_bot.rb` file:
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 path', # Skips the path assertion for just the users#create_invalid test
256
- 'path' # Skips the path assertion entirely in all tests
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 as well as entire tests.
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
- ### crud_test
472
+ ## Testing the test environment
266
473
 
267
- TODO
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
- ### devise_test
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
- TODO
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
- ### page_test
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
- TODO
482
+ If all environment tests pass, you will have a great experience with automated testing.
276
483
 
277
- ### member_test
484
+ ## Automated full stack testing
278
485
 
279
- TODO
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
- ### redirect_test
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
- ### wizard_test
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
- TODO
492
+ These are some quick ways to customize test bot's behaviour:
288
493
 
289
- ## Automated Testing / Rake tasks
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
- TODO
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
- ## Screenshots and Animated Gifs
511
+ To disable taking screenshots entirely set `config.screenshots = false` in the `config/initializers/effective_test_bot.rb` initializer file.
301
512
 
302
- TODO
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
- ```ruby
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:tourv # verbose mode
541
+ rake test:bot:tour TEST=posts#index
310
542
  ```
311
543
 
312
- ```ruby
313
- rake test:bot:tours # Prints out file location of all tour animated .gifs
314
- rake test:bot:purge # Deletes all tour and failure animated .gifs
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
- TODO
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
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveTestBot
2
- VERSION = '0.4.11'.freeze
2
+ VERSION = '0.4.12'.freeze
3
3
  end
@@ -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, true
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.11
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: 2015-12-17 00:00:00.000000000 Z
11
+ date: 2016-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails