バージョン
- ruby 3.2.2
- Rails 6.1.7.6
タスク管理アプリでの、タスクが降順に並んでいるかをRSpecでテストする
タスク管理アプリにて、投稿したタスクを降順に並べ、降順に並んでいるかをテストするために、「最新のタスクが一番上に表示される」、ということを確認するためのコードを書いたが、その時に学んだことを備忘録として残しておく。
FactoryBot.define do
factory :task do
name { 'パパ' }
content { '日曜日歯医者' }
end
end
RSpec.describe 'タスク管理機能', type: :system do
describe '新規作成機能' do
context 'タスクが作成日時の降順に並んでいる場合' do
it '新しいタスクが一番上に表示される' do
FactoryBot.create(:task, content: '自転車修理')
FactoryBot.create(:task, content: '買い物')
FactoryBot.create(:task, content: '洗濯')
visit tasks_path
list = all('.task_list')[0]
expect(list).to have_content '洗濯'
end
end
end
end
<h1><%= t('view.index') %></h1>
<div class="task_list">
<table>
<tr>
<th><%= t('view.task_name') %></th>
<th><%= t('view.content') %></th>
</tr>
<% @tasks.each do |task| %>
<tr>
<td><%= task.name %></td>
<td><%= task.content %></td>
<td><%= link_to t('view.detail'), task_path(task.id) %></td>
<td><%= link_to t('view.edit'), edit_task_path(task.id) %></td>
<td><%= link_to t('view.destroy'), task_path(task.id), method: :delete ,data: { confirm: '本当に削除していいですか?' } %></td>
</tr>
<% end %>
</table>
</div>
<%= link_to t('view.new_task'), new_task_path %>
テストが「洗濯」でも「買い物」でも「自転車修理」でも成功してしまう!なぜだ??
私は上記のようにコードを書いていました。
spec/system/task.rb
内で、下記のように3つのテストデータを作成するが、
FactoryBot.create(:task, content: '自転車修理')
FactoryBot.create(:task, content: '買い物')
FactoryBot.create(:task, content: '洗濯')
一番最新のデータはcontentが「洗濯」のデータなので、
expect(list).to have_content '洗濯'
の部分で、最新のデータに「洗濯」を含んでいることを確認する。
なのに、「洗濯」でも「買い物」でも「自転車修理」でも成功してしまうのです...なぜだ...
考えてみましたがわからなかったのでメンターさんに教えてもらいました。まず、
all('.task_list')
これは、htmlファイル内の、task_list
要素全てを、配列の形で取り出す。そして、
list = all('.task_list')[0]
とすることで、0番ということで、1番最初のデータが取り出され、それを変数list
に代入している。
問題は、app/views/tasks/index.html.erb
内の2行目
<div class="task_list">
これの位置。ここに書いてしまうと
このように、ひとつのtask_list
の中に、「自転車修理」も「買い物」も「洗濯」も全て含まれてしまっている。
なので変数list
の中にも、「自転車修理」も「買い物」も「洗濯」も全て含まれてしまうので、「洗濯」でも「買い物」でも「自転車修理」でもテストが成功してしまったのでした。
なので、class="task_list"
の位置を変えます。
<h1><%= t('view.index') %></h1>
<div>
<table>
<tr>
<th><%= t('view.task_name') %></th>
<th><%= t('view.content') %></th>
</tr>
<% @tasks.each do |task| %>
<tr class="task_list">
<td><%= task.name %></td>
<td><%= task.content %></td>
<td><%= link_to t('view.detail'), task_path(task.id) %></td>
<td><%= link_to t('view.edit'), edit_task_path(task.id) %></td>
<td><%= link_to t('view.destroy'), task_path(task.id), method: :delete ,data: { confirm: '本当に削除していいですか?' } %></td>
</tr>
<% end %>
</table>
</div>
<%= link_to t('view.new_task'), new_task_path %>
9行目に移動させました。すると、フォームビューで見てみると、
このように、「自転車修理」「買い物」「洗濯」それぞれに、class="task_list"
が付いているので、all('.task_list')[0]
には、1番最新のデータが入り、それが 変数list
に代入される。1番最新のtask_list
は、「パパ」「洗濯」なので、「洗濯」のみでテストは成功し、「買い物」「自転車修理」ではテストは不成功となる!!
初学者の私には、とーても新発見で面白かったので記事にしました!一緒に誰かのお役に立つと良いです。
本日は以上!!