フォーム入力・送信のテストを自動化しよう

学習の目標

本章では、以下の内容を学習します。

  • Railsにおけるフォーム実装の基本的な流れとフォームヘルパーの効果的な使用方法について実践的に学ぶ
  • システムスペックを使用したフォーム操作のテスト手法と、ユーザーの入力から送信までの一連の流れを検証する方法を習得する
  • コントローラとビューの連携の仕組みやフォームデータの適切な処理方法について理解を深める
  • RSpecのフォームテストに特化したメソッドの使い方とテストシナリオの組み立て方を学習する

はじめに

前回はシステムスペックの基礎と、Todoの一覧表示のテストについて学習しました。 一覧表示は静的な内容の確認でしたが、Webアプリケーションでは、ユーザーがフォームを通してデータを入力し、送信する機能が欠かせません。

本章では、新しいTodoを作成するためのフォームをテストする方法について学んでいきます。 実際のユーザーがブラウザで行う操作を、システムスペックで自動化する方法を習得しましょう。

フォーム画面の実装

フォームのテストを書く前に、まずは新規作成用のフォーム画面を実装していきましょう。 実際に動作するフォームを作成してから、その動作をテストコードで確認するという流れで進めます。

newアクションの実装

まず、コントローラにnewアクションを追加します。 app/controllers/todos_controller.rbを開いて、以下のコードを追加します。

class TodosController < ApplicationController
def index
@todos = Todo.all
end
def new
@todo = Todo.new
end
# 以下省略
end

newアクションでは、新しい空のTodoオブジェクトを作成しています。 このオブジェクトは、フォームを作る際のベースとなります。

フォームビューの作成

次に、new.html.erbというビューファイルを作成します。 このファイルは、app/views/todos/new.html.erbという場所に作ります。

<h1>新規Todo作成</h1>
<%= form_with(model: @todo, local: true) do |f| %>
<div>
<%= f.label :title, 'タイトル' %>
<%= f.text_field :title %>
</div>
<br>
<div>
<%= f.label :description, '説明' %>
<%= f.text_area :description %>
</div>
<div>
<%= f.submit '作成' %>
</div>
<% end %>
<%= link_to '一覧に戻る', todos_path %>

フォームの構成要素について

このフォームで使用している各要素について、詳しく説明していきましょう。

form_withは、Railsでフォームを作成するための便利なヘルパーメソッドです。 model: @todoと指定することで、このフォームがTodoモデルのデータを扱うことを示しています。

f.labelは、フォームの項目名(ラベル)を表示するためのヘルパーです。 たとえばf.label :title, 'タイトル'は、titleという項目に「タイトル」というラベルを付けています。

f.text_fieldf.text_areaは、実際に入力を行うフォーム部品を作成します。 titleには1行のテキスト入力(text_field)、descriptionには複数行のテキスト入力(text_area)を使用しています。

f.submitは、フォームの送信ボタンを作成します。

最後のlink_toは、一覧画面へのリンクを作成します。 todos_pathは、Railsが自動的に作成する一覧画面へのパス(URL)です。

フォーム処理の実装

フォームから送信されたデータを処理するために、createアクションも実装する必要があります。 todos_controller.rbに以下のコードを追加します。

class TodosController < ApplicationController
def index
@todos = Todo.all
end
def new
@todo = Todo.new
end
def create
@todo = Todo.new(todo_params)
if @todo.save
redirect_to todos_path, notice: '新しいTodoを作成しました'
else
render :new
end
end
# show, edit, update, destroyアクションは省略
# 一番下のendより上に以下のコードを追加
private
def todo_params
params.require(:todo).permit(:title, :description)
end
end

createアクションの動作解説

createアクションでは、フォームから送信されたデータを使って新しいTodoを作成しています。

todo_paramsというプライベートメソッドは、セキュリティのために必要なものです。 これにより、titleとdescriptionのみを受け付け、それ以外のデータは無視されます。 これをStrong Parametersと呼び、不正なデータの送信を防ぐ重要な仕組みです。

Todoの保存に成功したら、redirect_to todos_pathで一覧画面に戻ります。 失敗した場合は、render :newで新規作成画面を再表示します。

実装機能の動作確認

では、実装したTodoの新規作成機能が正しく動作するか確認してみましょう。 実際の操作を確認することで、後でテストコードを書く際の参考になります。

まず、bundle exec rails sというコマンドを実行して、Railsのサーバーを起動します。

bundle exec rails s

次に、ブラウザでhttp://localhost:3000/todosにアクセスしてみましょう。 すると、先ほどrails consoleで作成したTodoの一覧が表示されているはずです。

画面下部にある「新規作成」というリンクをクリックすると、新しいTodoを作成するためのフォーム画面が表示されます。

試しに以下のような内容を入力してみましょう。

  • タイトル:テストタイトル
  • 説明:テスト説明

「作成」ボタンをクリックすると、一覧画面に戻り、今入力したTodoが表示されているはずです。 この流れが確認できたら、ターミナルでCtrl+Cを押してRailsサーバーを停止します。

フォームのテスト実装

実際の動作が確認できたので、これをテストコードで表現していきましょう。 先ほどブラウザで行った操作を、システムスペックで自動化します。

spec/system/todos_spec.rbを開いて、新しいテストを追加します。

require 'rails_helper'
RSpec.describe 'Todo管理', type: :system do
before do
driven_by(:rack_test)
end
# 既存の一覧表示テスト
it 'Todo一覧を表示する' do
# ...existing code...
end
# 新規作成のテストを追加
it '新規Todoを作成できる' do
# Todoの新規作成ページへアクセス
visit new_todo_path
# フォームに値を入力
fill_in 'タイトル', with: 'RSpecを学ぶ'
fill_in '説明', with: 'システムスペックについて理解を深める'
# 作成ボタンをクリック
click_button '作成'
# 一覧画面に遷移していることを確認
expect(current_path).to eq todos_path
# 作成したTodoが表示されていることを確認
expect(page).to have_content('RSpecを学ぶ')
expect(page).to have_content('システムスペックについて理解を深める')
expect(page).to have_content('未完了')
end
end

テストコードの詳細解説

このテストコードで何をしているのか、一つずつ説明していきましょう。

ページへのアクセス

visit new_todo_pathは、先ほどブラウザで行った「新規作成画面を開く」という操作をコードで表現しています。 new_todo_pathは、新規作成画面へのパス(URL)で、Railsが自動的に生成してくれるものです。

フォーム入力の操作

fill_in 'タイトル', with: 'RSpecを学ぶ'は、フォームの「タイトル」という項目に「RSpecを学ぶ」という文字列を入力する操作です。 viewファイルでは、f.label :title, 'タイトル'というように、フォームの項目名を指定していました。

同じように、fill_in '説明', with: 'システムスペックについて理解を深める'は、説明の項目に文字列を入力する操作です。

フォーム送信の操作

click_button '作成'は、「作成」ボタンをクリックする操作を表しています。 このようにボタンをクリックすることで、フォームが送信され、新しいTodoが作成されます。

画面遷移の確認

また、expect(current_path).to eq todos_pathでは、作成ボタンを押した後、一覧画面に遷移していることを確認しています。 これにより、フォーム送信後の画面遷移が正しく動作していることを検証できます。

作成結果の確認

最後に、作成したTodoの内容が画面に表示されていることを確認しています。 これにより、フォームで入力したデータが正しくデータベースに保存され、画面に反映されていることを検証できます。

テストの実行

では、このテストを実行してみましょう。 bundle exec rspec spec/system/todos_spec.rbというコマンドを実行します。

$ bundle exec rspec spec/system/todos_spec.rb
Todo管理
Todo一覧を表示する
新規Todoを作成できる
Finished in 0.12487 seconds (files took 0.89012 seconds to load)
2 examples, 0 failures

テストが成功しました! これは、私たちが先ほどブラウザで確認した一連の操作が、テストでも正しく動作したということを示しています。

まとめ

本章では、フォームの実装とそのテストについて学習しました。

まず、Railsのフォームヘルパーを使ってTodo作成フォームを実装し、ブラウザで実際に操作して動きを確認しました。 その後、同じ操作をシステムスペックとして記述することで、フォーム機能の自動テストを作成しました。

システムスペックでは、visitでページにアクセスし、fill_inでフォーム入力を行い、click_buttonでボタンをクリックするという、実際のユーザー操作を忠実に再現できることがわかりました。

次回は、バリデーションエラーの場合のテストなど、より実践的なフォームのテストについて学んでいきます。

このセクションは有料サブスクリプションへの登録、またはログインが必要です。完全なコンテンツにアクセスするには、料金ページ(/pricing)をご覧ください。購入済みの場合は、ログインしてください。

Basicプランでより詳しく学習

この先のコンテンツを読むにはBasicプラン以上が必要です。より詳細な解説、実践的なサンプルコード、演習問題にアクセスして学習を深めましょう。

作成者:とまだ
Previous
RSpeccとCapybaraでブラウザ操作をテストしよう