aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source/testing.md
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source/testing.md')
-rw-r--r--guides/source/testing.md189
1 files changed, 185 insertions, 4 deletions
diff --git a/guides/source/testing.md b/guides/source/testing.md
index 6f783089a9..652030a733 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -8,7 +8,7 @@ This guide covers built-in mechanisms in Rails for testing your application.
After reading this guide, you will know:
* Rails testing terminology.
-* How to write unit, functional, and integration tests for your application.
+* How to write unit, functional, integration, and system tests for your application.
* Other popular testing approaches and plugins.
--------------------------------------------------------------------------------
@@ -33,18 +33,27 @@ Rails creates a `test` directory for you as soon as you create a Rails project u
```bash
$ ls -F test
-controllers/ helpers/ mailers/ test_helper.rb
-fixtures/ integration/ models/
+controllers/ helpers/ mailers/ system/ test_helper.rb
+fixtures/ integration/ models/ application_system_test_case.rb
```
The `helpers`, `mailers`, and `models` directories are meant to hold tests for view helpers, mailers, and models, respectively. The `controllers` directory is meant to hold tests for controllers, routes, and views. The `integration` directory is meant to hold tests for interactions between controllers.
+The system test directory holds system tests, which are used for full browser
+testing of your application. System tests allow you to test your application
+the way your users experience it and help you test your JavaScript as well.
+System tests inherit from Capybara and perform in browser tests for your
+application.
+
Fixtures are a way of organizing test data; they reside in the `fixtures` directory.
A `jobs` directory will also be created when an associated test is first generated.
The `test_helper.rb` file holds the default configuration for your tests.
+The `application_system_test_case.rb` holds the default configuration for your system
+tests.
+
### The Test Environment
@@ -358,6 +367,7 @@ All the basic assertions such as `assert_equal` defined in `Minitest::Assertions
* [`ActionView::TestCase`](http://api.rubyonrails.org/classes/ActionView/TestCase.html)
* [`ActionDispatch::IntegrationTest`](http://api.rubyonrails.org/classes/ActionDispatch/IntegrationTest.html)
* [`ActiveJob::TestCase`](http://api.rubyonrails.org/classes/ActiveJob/TestCase.html)
+* [`ActionDispatch::SystemTestCase`](http://api.rubyonrails.org/classes/ActionDispatch/SystemTestCase.html)
Each of these classes include `Minitest::Assertions`, allowing us to use all of the basic assertions in our tests.
@@ -587,6 +597,177 @@ create test/fixtures/articles.yml
Model tests don't have their own superclass like `ActionMailer::TestCase` instead they inherit from [`ActiveSupport::TestCase`](http://api.rubyonrails.org/classes/ActiveSupport/TestCase.html).
+System Testing
+--------------
+
+System tests are full-browser tests that can be used to test your application's
+JavaScript and user experience. System tests use Capybara as a base.
+
+System tests allow for running tests in either a real browser or a headless
+driver for testing full user interactions with your application.
+
+For creating Rails system tests, you use the `test/system` directory in your
+application. Rails provides a generator to create a system test skeleton for you.
+
+```bash
+$ bin/rails generate system_test users_create_test
+ invoke test_unit
+ create test/system/users_create_test.rb
+```
+
+Here's what a freshly-generated system test looks like:
+
+```ruby
+require "application_system_test_case"
+
+class UsersCreateTest < ApplicationSystemTestCase
+ visit users_url
+
+ assert_selector "h1", text: "Users"
+end
+```
+
+By default, system tests are run with the Selenium driver, using the Chrome
+browser, and a screen size of 1400x1400. The next section explains how to
+change the default settings.
+
+### Changing the default settings
+
+Rails makes changing the default settings for system tests very simple. All
+the setup is abstracted away so you can focus on writing your tests.
+
+When you generate a new application or scaffold, an `application_system_test_case.rb` file
+is created in the test directory. This is where all the configuration for your
+system tests should live.
+
+If you want to change the default settings you can simply change what the system
+tests are "driven by". Say you want to change the driver from Selenium to
+Poltergeist. First add the Poltergeist gem to your Gemfile. Then in your
+`application_system_test_case.rb` file do the following:
+
+```ruby
+require "test_helper"
+require "capybara/poltergeist"
+
+class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
+ driven_by :poltergeist
+end
+```
+
+The driver name is a required argument for `driven_by`. The optional arguments
+that can be passed to `driven_by` are `:using` for the browser (this will only
+be used for non-headless drivers like Selenium), `:on` for the port Puma should
+use, and `:screen_size` to change the size of the screen for screenshots.
+
+```ruby
+require "test_helper"
+
+class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
+ driven_by :selenium, using: :firefox
+end
+```
+
+If your Capybara configuration requires more setup than provided by Rails, all
+of that configuration can be put into the `application_system_test_case.rb` file.
+
+Please see [Capybara's documentation](https://github.com/teamcapybara/capybara#setup)
+for additional settings.
+
+### Screenshot Helper
+
+The `ScreenshotHelper` is a helper designed to capture screenshots of your tests.
+This can be helpful for viewing the browser at the point a test failed, or
+to view screenshots later for debugging.
+
+Two methods are provided: `take_screenshot` and `take_failed_screenshot`.
+`take_failed_screenshot` is automatically included in `after_teardown` inside
+Rails.
+
+The `take_screenshot` helper method can be included anywhere in your tests to
+take a screenshot of the browser.
+
+### Implementing a system test
+
+Now we're going to add a system test to our blog application. We'll demonstrate
+writing a system test by visiting the index page and creating a new blog article.
+
+If you used the scaffold generator, a system test skeleton is automatically
+created for you. If you did not use the generator start by creating a system
+test skeleton.
+
+```bash
+$ bin/rails generate system_test articles
+```
+
+It should have created a test file placeholder for us. With the output of the
+previous command you should see:
+
+```bash
+ invoke test_unit
+ create test/system/articles_test.rb
+```
+
+Now let's open that file and write our first assertion:
+
+```ruby
+require "application_system_test_case"
+
+class ArticlesTest < ApplicationSystemTestCase
+ test "viewing the index" do
+ visit articles_path
+ assert_selector "h1", text: "Articles"
+ end
+end
+```
+
+The test should see that there is an h1 on the articles index and pass.
+
+Run the system tests.
+
+```bash
+bin/rails test:system
+```
+
+#### Creating articles system test
+
+Now let's test the flow for creating a new article in our blog.
+
+```ruby
+test "creating an article" do
+ visit articles_path
+
+ click_on "New Article"
+
+ fill_in "Title", with: "Creating an Article"
+ fill_in "Body", with: "Created this article successfully!"
+
+ click_on "Create Article"
+
+ assert_text "Creating an Article"
+end
+```
+
+The first step is to call `visit articles_path`. This will take the test to the
+articles index page.
+
+Then the `click_on "New Article"` will find the "New Article" button on the
+index page. This will redirect the browser to `/articles/new`.
+
+Then the test will fill in the title and body of the article with the specified
+text. Once the fields are filled in, "Create Article" is clicked on which will
+send a POST request to create the new article in the database.
+
+We will be redirected back to the the articles index page and there we assert
+that the text from the article title is on the articles index page.
+
+#### Taking it further
+
+The beauty of system testing is that it is similar to integration testing in
+that it tests the user's interaction with your controller, model, and view, but
+system testing is much more robust and actually tests your application as if
+a real user were using it. Going forward, you can test anything that the user
+themselves would do in your application such as commenting, deleting articles,
+publishing draft articles, etc.
Integration Testing
-------------------
@@ -868,7 +1049,7 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest
assert_equal "index", @controller.action_name
assert_equal "application/x-www-form-urlencoded", @request.media_type
- assert_match "Articles", @response.body
+ assert_match "Articles", @response.body
end
end
```