初めてのRSpecで学んだこと　No.2

## バージョン
- ruby 3.2.2
- Rails 6.1.7.6
-------------------------

## タスク管理アプリでの、タスクが降順に並んでいるかをRSpecでテストする
タスク管理アプリにて、投稿したタスクを降順に並べ、降順に並んでいるかをテストするために、「最新のタスクが一番上に表示される」、ということを確認するためのコードを書いたが、その時に学んだことを備忘録として残しておく。
```spec/factories/tasks.rb
FactoryBot.define do
  factory :task do
    name { 'パパ' }
    content { '日曜日歯医者' }
  end
end
```

```spec/system/task.rb
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
```
```app/views/tasks/index.html.erb
<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`内で、下記のように３つのテストデータを作成するが、
```
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]
```
とすることで、０番ということで、１番最初のデータが取り出され、それを変数`list`に代入している。

問題は、`app/views/tasks/index.html.erb`　内の2行目
```
<div class="task_list">
```
これの位置。ここに書いてしまうと
![スクリーンショット 2023-11-29 14.29.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3566175/a631b2e9-f2a6-fbce-2d98-93b770b9228a.png)
このように、ひとつの`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行目に移動させました。すると、フォームビューで見てみると、
![スクリーンショット 2023-11-29 14.40.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3566175/eeaf5668-85b0-046a-0485-45bf6de7a6c7.png)
このように、「自転車修理」「買い物」「洗濯」それぞれに、`class="task_list"`が付いているので、`all('.task_list')[0]`　には、1番最新のデータが入り、それが 変数`list`に代入される。１番最新の`task_list`は、「パパ」「洗濯」なので、「洗濯」のみでテストは成功し、「買い物」「自転車修理」ではテストは不成功となる！！

初学者の私には、とーても新発見で面白かったので記事にしました！一緒に誰かのお役に立つと良いです。
本日は以上！！