RSpec編4

2021.4.29

時間がかかってしまった...。

調べ方が難しかった。

trait使い方

参照

FactoryBot Traits - Qiita

FactoryBotでtraitを使おう - Qiita

今回の場合

(spec/factories/task.rb)に定義する

FactoryBot.define do
factory :task do
title { 'Task' }
status { :todo }
from = Date.parse("2019/08/01")
to = Date.parse("2019/12/31")
deadline { Random.rand(from..to) }

trait :done do
status { :done }
completion_date { Time.current.yesterday }
end
end
end

 

通常の書き方statustodoの通常のtaskになる。

let(:task) { create(:task, project_id: project.id) }

 

traitを活用した書き方statusdonecompletion_dateTime.current.yesterdayのtaskが作成される。

*第一引数に:task第二引数にtraitで定義したもの=:doneを追加する。

let(:task_done) { create(:task, :done, project_id: project.id)}

 

randメソッド

FactoryBot.define do
factory :task do
title { 'Task' }
status { rand(2) } #0以上2未満の整数を返す
省略

参照

【Ruby】randメソッドの使い方を学んでランダムなデータを作成しよ | Pikawaka - ピカ1わかりやすいプログラミング用語サイト

 

short_timeメソッド

時刻表示の実装に違いがあり、エラーが出た。

参照

RSpecの日付表示を、viewで使っているメソッドに合わせて修正 - Kuni-Blog

【Rails】Time.currentとTime.nowの違い - Qiita

 

(spec/system/task_spec.rb)

 (元々の入力)

expect(find('.task_list')).to have_content(Time.current.strftime('%Y-%m-%d')

strftimeメソッド

【Rails】strftimeの使い方ついて徹底解説! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト

日時データを指定したフォーマットデータを指定したフォーマットで文字列に変換できるメソッド

これを使用してもテストを通すことはできるのだが、viewの表示だ変更されたときにエラーになってしまうので、使用しない。

→viewで使用しているメソッドを使用して変更する

 

(views/tasks/index.html.erb)

<tbody class='task_list'>
<% @tasks.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.status %></td>
<td><%= short_time(task.deadline) if task.deadline? %></td>
<td><%= link_to 'Show', [@project, task] %></td>
<td><%= link_to 'Edit', edit_project_task_path(@project, task) %></td>
<td><%= link_to 'Destroy', [@project, task], method: :delete, data:
{ confirm: 'Are you sure?' } %></td>
</tr>
<% end %>

 viewではshoet_timeメソッドを使用しているので、それを使用して修正する。

(spec/system/task_spec.rb)(変更後)

context '正常系' do
it 'Taskを編集した場合、一覧画面で編集後の内容が表示されること' do
# FIXME: テストが失敗するので修正してください
visit edit_project_task_path(project, task)
fill_in 'Deadline', with: Time.current
click_button 'Update Task'
click_link 'Back'
expect(find('.task_list')).to have_content(short_time(Time.current))
expect(current_path).to eq project_tasks_path(project)
end

 

しかし、テストを実行すると、失敗する。

ApplicationHelperを読み込んでいなかったためshort_timeメソッドが使用できない。

(spec/rails_helper.rb)

RSpec.configure do |config|
省略
 
config.include ApplicationHelper #追加
end

ApplicationHelperを追加したので、テストが通るようになる。

 

confirmダイアログのテストをする

(views/projects/index.html.erb)

<td><%= link_to 'Destroy', project, method: :delete,
data: { confirm: 'Are you sure?' } %></td>

↓confirmダイアログでOKを選択する

 
page.driver.browser.switch_to.alert.accept

参照

キャンセルなどの方法もここに載っている

【Rails】Selenium/RSpecでconfirmダイアログのテストをする - Qiita

 

expect(find())について

要素を検索する。

Capybaraチートシート - Qiita

 

今回の場合、expect(find('.task_list'))

it 'Taskが削除されること' do
visit project_tasks_path(project)
click_link 'Destroy'
page.driver.browser.switch_to.alert.accept
expect(find('.task_list')).not_to have_content task.title
expect(Task.count).to eq 0
expect(current_path).to eq project_tasks_path(project)
end

(views/tasks/index.html.erb)のクラス='task_list'を指定

クラスないから指定しないと、noticeが検出されてしまう。

<tbody class='task_list'>
<% @tasks.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.status %></td>
<td><%= short_time(task.deadline) if task.deadline? %></td>
<td><%= link_to 'Show', [@project, task] %></td>
<td><%= link_to 'Edit', edit_project_task_path(@project, task) %></td>
<td><%= link_to 'Destroy', [@project, task], method: :delete, data:
{ confirm: 'Are you sure?' } %></td>
</tr>
<% end %>

 

これも読んだほうがいい

RUNTEQ(ランテック) - Webエンジニアの採用基準可視化サービス | RUNTEQ(ランテック)

 

target="blank"のテスト

(views/projects/show.html.erb)

<%= link_to 'View Todos', project_tasks_path(@project),
target:'_blank', rel: 'noopener' %>

target:'_blank' リンクを新しいウィンドウで表示する

rel: 'noopener' 一種のセキュリティ対策。target:'_blank' がついたときに自動で付くようになっている

参照

target=”_blank” の正しい使い方講座 |SEO Japan by アイオイクス

aタグに付いているrel="noopener"って何? | ocws BLOG

今回この形でエラーが出てしまった。

新しいウィンドウで表示することを記入していないから。

it 'Project詳細からTask一覧ページにアクセスした場合、Taskが表示されること' do
# FIXME: テストが失敗するので修正してください
visit project_path(project)
click_link 'View Todos'
expect(page).to have_content task.title
expect(Task.count).to eq 1
expect(current_path).to eq project_tasks_path(project)
end

(変更後)

it 'Project詳細からTask一覧ページにアクセスした場合、Taskが表示されること' do
# FIXME: テストが失敗するので修正してください
visit project_path(project)
click_link 'View Todos'
switch_to_window(windows.last) #追記 これで別のタブに移動する。
expect(page).to have_content task.title
expect(Task.count).to eq 1
expect(current_path).to eq project_tasks_path(project)
end

 

参照

Capybaraと仲良くなる(タブ・ウィンドウの操作について) - Qiita

 

associationを使用し、省略する

 

1 FactoryBotにassociationを記述

FactoryBot.define do
factory :task do
title { 'Task' }
status { rand(2) }
from = Date.parse("2019/08/01")
to = Date.parse("2019/12/31")
deadline { Random.rand(from..to) }
association :project

2  データを作成

project_idにproject.idが自動で入るようになるので、省略可能

let(:task_done) { create(:task, :done, project_id: project.id )}

RSpec.describe 'Task', type: :system do
let(:task) { create(:task) }
let(:task_done) { create(:task, :done)}

 

参照

【FactoryBot】associationの使い方 - Qiita

 

コミットの際はPrefixをつける

コミットの際に他の人からわかりやすいように、 Prefixをつけるようにする。

参照

誰にとってもわかりやすいGitのコミットメッセージを考える | Tips Note by TAM