The Ruby on Rails 5 Quick Learning Practice Guide that can be used in the field is written by RSpec because it is widely used in the development field. However, for those who are learning for the first time, RSpec may seem a little difficult.
Here, I will try Minitest, which is the standard testing framework of Ruby on Rails and allows you to write tests concisely.

Added minitest to Gemfile. Minitest-reporters make it easier to see the test results.
# Gemfile
group :test do
  gem 'capybara'                     #Virtually operate the user's browser
  gem 'selenium-webdriver'
  gem 'webdrivers'
  gem 'minitest'                     #Rails standard testing framework
  gem 'minitest-reporters'           #Easy-to-read display of test results
end
With minitest-reporters, you can easily see the test results and Add login_helper so that you can test the login and logout of users.
# test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require_relative 'login_helper'
require 'rails/test_help'
require 'minitest/reporters'
Minitest::Reporters.use!
class ActiveSupport::TestCase
  # parallelize(workers: :number_of_processors)
  parallelize(workers: 1) #Click here if you get an error
  fixtures :all
end
# test/login_helper.rb
module LoginHelper
  def login_as(user)
    visit login_url
    fill_in 'mail address', with: user.email
    fill_in 'password', with: 'password'
    click_on 'log in'
    @current_user = user
  end
  def current_user
    @current_user
  end
end
Prepare a fixture. Fixture means built-in furniture in English. Rails will automatically load this fixture into your test database. There are more sophisticated gems such as Factory-bot for creating sample data, but here we will use fixtures that do not require any settings and can be introduced in a concise and easy-to-understand manner.
# test/fixtures/users.yml
#General user taro
taro:
  name: taro
  email: [email protected]
  password_digest: <%=BCrypt::Password.create('password', cost: BCrypt::Engine::MIN_COST)%>
  admin: true
#Admin admin
admin:
  name: admin
  email: [email protected]
  password_digest: <%=BCrypt::Password.create('password', cost: BCrypt::Engine::MIN_COST)%>
  admin: true
#You can also create ten users.
<% 1.upto(10) do |i| %>
user_<%= i %>:
  name: user_<%= i %>
  email: user_<%= i %>@example.com
  password_digest: <%=BCrypt::Password.create('password', cost: BCrypt::Engine::MIN_COST)%>
  admin: false
<% end %>
You can also set the association by writing user: taro for fixture.
# test/fixtures/tasks.yml
taro_task:
  name:Taro's task
  description:Various task descriptions
  user: taro
The system test is a test when the user actually operates the web application with a browser. It may take some time to execute, but it is convenient because it can imitate the user's operation and if it fails, a screenshot will be taken automatically.
Rails implements generators to make it easier to create system tests.
% rails g system_test welcomes
By executing this command, a system test template will be created, so we will modify it a little.
# test/system/welcomes_test.rb
require "application_system_test_case"
class WelcomesTest < ApplicationSystemTestCase
  test "Taskleaf is displayed on the top page" do
    visit root_url
    assert_selector "h1", text: "Taskleaf"
  end
end
You can run all system tests with the following command.
% rails test:system
To run some tests, use the following command:
% rails test test/system/welcomes_test.rb
The system test seems to have failed.

If it fails, a screenshot will be taken automatically.
 /Users/mirai/rails_projects/
taskleaf/tmp/screenshots/
 failures_test_ Top page shows _Taskleaf_.png ```
 Is displayed, so you can check it in Finder.
 Based on the screenshot, fix the error and try again.
 
 The system test passed successfully.
### User test
``` ruby
# test/system/users_test.rb
require "application_system_test_case"
class UsersTest < ApplicationSystemTestCase
  setup do
    @user = users(:taro)
  end
  test "If the password is correct, you can log in" do
    visit login_url
    fill_in 'mail address', with: @user.email
    fill_in 'password', with: 'password'
    click_on 'log in'
    assert_selector ".ui.success.message", text: "You are now logged"
  end
  test "If the password is different, you cannot log in" do
    visit login_url
    fill_in 'mail address', with: @user.email
    fill_in 'password', with: 'wrong password'
    click_on 'log in'
    assert_selector ".ui.error.message", text: "Email address or password is different"
  end
end
Pre-preparing with the setup block is useful because it can be used forever in subsequent tests.
# test/system/tasks_test.rb
require "application_system_test_case"
class TasksTest < ApplicationSystemTestCase
  setup do
    @taro       = users(:taro)
    @jiro       = users(:jiro)
    @taro_task1 = tasks(:taro_task1)
    @taro_task2 = tasks(:taro_task2)
    @taro_task3 = tasks(:taro_task3)
    @jiro_task1 = tasks(:jiro_task1)
  end
  test "When you log in with Taro, the tasks created by Taro are listed." do
    login_as(@taro)
    visit tasks_path
    assert_text @taro_task1.name
    assert_text @taro_task2.name
    assert_text @taro_task3.name
  end
  test "When you log in with Taro, the tasks created by Taro are displayed in detail." do
    login_as(@taro)
    visit task_path(@taro_task1)
    assert_text @taro_task1.name
    assert_text @taro_task1.description
  end
  test "When I log in with Jiro, the tasks created by Taro are not displayed." do
    login_as(@jiro)
    visit tasks_path
    assert_no_text @taro_task1.name
  end
  test "You can register a task by entering a name on the new creation screen." do
    login_as(@taro)
    visit new_task_path
    fill_in 'name', with: 'New Taro's task'
    click_on 'register'
    assert_selector '.ui.success.message', text: 'New Taro's task'
    within 'table' do
      assert_text 'New Taro's task'
    end
  end
  test "If there is no name on the new creation screen, an error will be displayed" do
    login_as(@taro)
    visit new_task_path
    fill_in 'name', with: '   '
    click_on 'register'
    within '#error_explanation' do
      assert_text 'Please enter your name'
    end
  end
  test "You can edit your own tasks" do
    login_as(@taro)
    visit tasks_path
    click_on 'Editing', match: :first
    fill_in 'name', with: 'Edited Taro's task'
    click_on 'Update'
    assert_selector '.ui.success.message', text: 'Edited Taro's task'
    within 'table' do
      assert_text 'Edited Taro's task'
    end
  end
  test "You can delete your task" do
    login_as(@taro)
    assert_equal 3, current_user.tasks.count
    visit tasks_path
    click_on 'Delete', match: :first
    accept_confirm
    assert_selector '.ui.success.message', text: 'It has been deleted'
    assert_equal 2, current_user.tasks.count
  end
end
You can also test sending emails.
# test/mailers/task_mailer_test.rb
require 'test_helper'
class TaskMailerTest < ActionMailer::TestCase
  #Advance preparation
  setup do
    @user = users(:taro)
    @task = @user.tasks.create(name: 'Today's task',
                               description: 'Learn Ruby on Rails')
    @mail = TaskMailer.creation_email(@task)
  end
  test "A task creation completion email is sent" do
    #Test if email is sent
    assert_emails 1 do
      @mail.deliver_now
    end
    #Test if you sent the email you expected
    assert_equal "Task creation completion email", @mail.subject
    assert_equal [@user.email], @mail.to
    assert_equal ["[email protected]"], @mail.from
    assert_match "Today's task", @mail.html_part.body.to_s
    assert_match "Learn Ruby on Rails", @mail.html_part.body.to_s
    assert_match "Today's task", @mail.text_part.body.to_s
    assert_match "Learn Ruby on Rails", @mail.text_part.body.to_s
  end
end
Run your mailer test with the following command:
% rails test test/mailers
How was the introduction of the minitest that you can write concisely? We hope you find it useful.
Rails Testing Guide (https://railsguides.jp/testing.html)
Recommended Posts