編集フォームでの更新テストを自動化しよう
学習の目標
本章では、以下の内容を学習します。
- Railsアプリケーションにおける編集機能の基本的な実装方法について、コントローラからビューまでの一連の流れを体系的に理解する
- 既存のレコードを安全に更新するための設計パターンと、Strong Parametersを活用したセキュアな実装手法を習得する
- システムスペックにおける事前データの準備方法と、beforeブロックを使用した効率的なテストコードの書き方を学ぶ
- 一覧画面から編集画面への遷移、データの更新、エラー処理など、実際のユーザー操作を想定したテストシナリオの組み立て方を実践的に理解する
はじめに
前回はバリデーションのテストについて学習しました。 新規作成機能では、空のデータにユーザーが情報を入力する流れでしたが、実際のWebアプリケーションでは、既存のデータを修正する編集機能も重要な要素です。
本章では、既存のTodoを編集する機能のテストを実装していきます。 編集機能では、既存データの取得、フォームでの表示、更新処理という一連の流れをテストすることになります。
編集機能の実装
まずはコントローラの実装から始めましょう。 編集機能では、データの表示と更新の2つのアクションが必要になります。
コントローラの実装
app/controllers/todos_controller.rb
を開きます。 前回のrails generate
コマンドで、edit
アクションとupdate
アクションの雛形は作られていますが、実装はまだ行われていません。
これらのアクションを以下のように実装していきます。
class TodosController < ApplicationController # 既存のアクション(index, new, create)は省略
def edit @todo = Todo.find(params[:id]) end
def update @todo = Todo.find(params[:id]) if @todo.update(todo_params) redirect_to todos_path else render :edit end end
private
def todo_params params.require(:todo).permit(:title, :description) endend
コントローラの動作解説
このコードについて説明していきましょう。
edit
アクションでは、URLのパラメータ(id)を使って編集対象のTodoを取得します。 このTodoは、編集用フォームで使用されます。
update
アクションでは、同じくURLのパラメータからTodoを取得し、フォームから送信されたデータで更新を試みます。 更新に成功したら一覧画面に戻り、失敗した場合は編集画面を再表示します。
編集フォームの作成
次に、編集用のビューファイルを作成します。 app/views/todos/edit.html.erb
を開きます。
これも雛形が生成されていますが、実装はまだ行われていないため、以下のように実装していきます。
<h1>Todo編集</h1>
<% if @todo.errors.any? %> <div class="error-messages"> <h2><%= @todo.errors.count %>件のエラーがあります</h2> <ul> <% @todo.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div><% end %>
<%= 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 %>
このフォームは、新規作成のフォームとほぼ同じ構造です。 主な違いは、タイトルが「Todo編集」になっていることと、送信ボタンのラベルが「更新」に変更されている点です。
一覧画面への編集リンクの追加
続いて、一覧画面から編集画面へ移動できるように、リンクを追加します。 ユーザーが直感的に編集操作を行えるようにするためです。
app/views/todos/index.html.erb
を開いて、各Todoの表示部分に編集リンクを追加します。
<h1>Todo一覧</h1>
<div class="todos"> <% @todos.each do |todo| %> <div class="todo"> <h2><%= todo.title %></h2> <p><%= todo.description %></p> <p> 状態: <%= todo.completed ? "完了" : "未完了" %> <%= link_to '編集', edit_todo_path(todo) %> </p> </div> <% end %></div>
<%= link_to '新規作成', new_todo_path %>
動作確認
では、bundle exec rails s
でサーバーを起動して、編集機能が正しく動作するか確認してみましょう。
bundle exec rails s
ブラウザでhttp://localhost:3000/todos
にアクセスし、以下の操作を行います。
まず、一覧画面に表示されているTodoの「編集」リンクをクリックします。 次に、タイトルと説明を変更してみましょう。 最後に、「更新」ボタンをクリックします。
一覧画面に戻り、変更した内容が反映されていることを確認します。 動作確認ができたら、Ctrl+Cでサーバーを停止します。
編集機能のテストの実装
実際の動作が確認できたので、これをテストコードで表現していきましょう。 編集機能では、既存データの準備、編集画面への遷移、データの更新という流れをテストします。
spec/system/todos_spec.rb
に編集機能のテストを追加します。
require 'rails_helper'
RSpec.describe 'Todo管理', type: :system do # 既存のテストは省略...
describe '編集' do # テストで使用するTodoを準備 before do @todo = Todo.create!( title: 'テスト駆動開発', description: 'アプリケーションをテスト駆動で実装する' ) end
it 'Todoを編集できる' do # Todo一覧画面を表示 visit todos_path
# 編集リンクをクリック click_link '編集'
# フォームに新しい値を入力 fill_in 'タイトル', with: 'RSpec入門' fill_in '説明', with: 'システムスペックについて理解を深める'
# 更新ボタンをクリック click_button '更新'
# 一覧画面に遷移していることを確認 expect(current_path).to eq todos_path
# 変更した内容が表示されていることを確認 expect(page).to have_content('RSpec入門') expect(page).to have_content('システムスペックについて理解を深める') end
it '編集画面で不正な値を入力するとエラーメッセージが表示される' do # 編集画面を表示 visit edit_todo_path(@todo)
# 不正な値を入力 fill_in 'タイトル', with: '' # タイトルを空に fill_in '説明', with: '短すぎ' # 説明を10文字未満に
# 更新ボタンをクリック click_button '更新'
# エラーメッセージが表示されることを確認 expect(page).to have_content('Title can\'t be blank') expect(page).to have_content('too short') end endend
テストコードの詳細解説
このテストについて説明していきましょう。
テストデータの準備
まずbefore
ブロックを使用してテストで使用するTodoを作成し、後に編集画面を表示するときのために@todo
というインスタンス変数に格納しています。 このTodoは、各テストケースで必要になったときに利用できるように準備されます。
正常系のテスト
次に、正常系と異常系の2つのテストケースを実装しました。
正常系のテストでは以下の点を確認しています。
まず、一覧画面から編集画面に移動できることを確認します。 次に、フォームに新しい値を入力できることをテストします。 最後に、更新後に一覧画面に戻り、変更が反映されていることを検証します。
異常系のテスト
異常系のテストでは以下の点を確認しています。
バリデーションエラーが正しく機能することを検証します。 また、エラーメッセージが適切に表示されることも確認します。
テストの実行
では、テストを実行してみましょう。
$ bundle exec rspec spec/system/todos_spec.rb
Todo管理 Todo一覧を表示する 新規Todoを作成できる バリデーション タイトルと説明が未入力の場合、エラーメッセージが表示される 説明が10文字未満の場合、エラーメッセージが表示される エラー後、正しい入力で登録できる 編集 Todoを編集できる 編集画面で不正な値を入力するとエラーメッセージが表示される
Finished in 0.12487 seconds (files took 0.89012 seconds to load)7 examples, 0 failures
全てのテストが成功しました!これにより、編集機能が期待通りに動作していることが確認できます。
まとめ
本章では、編集機能の実装とそのテストについて学習しました。
具体的には以下の点をテストできるようになりました。 まず、Todo一覧画面から編集画面への遷移ができることを確認できます。 次に、編集フォームでの値の更新が正しく行えることを検証できます。 そして、バリデーションエラーが適切に処理されることも確認できます。
編集機能のテストでは、既存データの準備から更新処理まで、一連の流れを包括的にテストできました。
Basicプランでより詳しく学習
この先のコンテンツを読むにはBasicプラン以上が必要です。より詳細な解説、実践的なサンプルコード、演習問題にアクセスして学習を深めましょう。