Everyday Rails - RSpec による Rails テスト入門を読んで

we don’t recommend adding the rails-controller-testing gem to your application. The official recommendation of the Rails team and the RSpec core team is to write request specs instead
Rails5からcontrollerのテストは非推奨
コントローラスペックは、コントローラの内部ロジックに焦点を当てていますが、ルーティングやミドルウェアの影響を受けないため、実際のアプリケーションの動作を完全には再現できません。

をクローン

test DBの設定については config/database.yml
に記載がある

.rspec
で、テスト結果を見やすくするなどの設定を記述する
--require spec_helper
--format documentation

binstub
を使うかどうかは任意
使う場合は bin/rspec
で起動
使わない場合は bundle exec rspec
で起動

UI 関連のテストは統合テストに任せようとしています。これは Rails 開発者
の中では標準的なプラクティスです。

3. モデルスペック
バリデーションのテストケースでは、モデルをnewして、save!してバリデーションを発火させるのはやりすぎ。以下の方法がある
・valid?
で発火させる。
・be_valid
を使う◎
# 保存する前に、バリデーションを発火させた状態を確認できる
expect(setting).to be_valid
itの中でletなど使わずに変数を宣言する書き方もある
各itの中で使うようであれば、@userのようにしてbeforeに移動する
it "returns notes that match the search term" do
user = User.create(
first_name: "Joe",
last_name: "Tester",
email: "joetester@example.com",
password: "dottle-nouveau-pavilion-tights-furze",
)
project = user.projects.create(
name: "Test Project",
)
describe と contextの使い分け
describe ではクラスやシステムの機能に関するアウトラインを記述し、
context では特定の状態に関するアウトラインを記述するようにします。

4. 意味のあるテストデータの作成 P47~
テストで使うデータをどう作るかという話。
- フィクスチャ (デフォルトで使える様になってる仕組み)
- factory (gem)
がある
"factory_bot_rails"
をgemに追加する Rails以外の Ruby コードで Factory Botを使うことはできる。
factoryを使うときのtips
-
project_attributes = FactoryBot.attributes_for(:project)
ファクトリで定義された全ての属性を含むハッシュを生成。これはデータベースにオブジェクトを保存せず、メモリ上にモデルインスタンスも作成しない。 - シーケンスを使うと、モデルのデータをまとめて作るときに、値が重複することを防ぐことができる
factory :user do
sequence(:email) { |n| "tester#{n}@example.com" }
end
- factoryの中で
association : XXX
を使うと、関連するXXXというデータを同時に作成できる - 作成はせず、作成済のデータを関連付けるだけにすることもできる
FactoryBot.define do
factory :note do
message "My important note."
association :project
user { project.owner } # association : userにすると、別のユーザーができてしまうので`project.owner` にする
end end
factoryの重複を減らすtips
- 継承を表現する(入れ子構造になる)
factory :project do
sequence(:name) { |n| "Test Project #{n}" }
description "Sample project for testing purposes"
due_on 1.week.from_now
association :owner
factory :project_due_yesterday do
due_on 1.day.ago # 他の属性について定義しなくてよい!
end
end
FactoryBot.create(:project_due_tomorrow)
- traitを使用する(入れ子構造になる)
trait :due_yesterday do
due_on 1.day.ago
end
FactoryBot.create(:project, :due_yesterday)
コールバック
- traitと
before
やafter
を組み合わせると、明示的にコールバックを呼び出せる - 他にも方法はあるが、ファクトリを使うたびに呼び出されないよう、traitの中で使うのが安全
trait :with_notes do
after(:create) { |project| create_list(:note, 5, project: project) }
end
FactoryBot.create(:project, :with_notes) # traitを呼び出すとコールバックが発火する
注意
可能な限り FactoryBot.create よりも FactoryBot.build を使う。buildはデータの永続化を行わないため高速。

5. コントローラスペック P70~
-
response
は予約語。ブラウザに返すべきアプリケーションの全データを保持している - Rails5からcontrollerのテストは非推奨
- 7章へ

6. フィーチャスペックで UI をテストする P95~
- フィーチャスペック = 受入テスト 、または 統合テスト
- のちのアップデートで、システムスペックに変わったので注意
- rails標準では
Minitest
を使えるようになっているが、Capybara
を使用する例が紹介されている。ブラウザの操作をシミュレートするために Capybaraを使う。Rails 5.1からは、Capybara
はすでにインストールされている。
Capybaraのテクニック
- テストが失敗して、ブラウザの様子が見たいときは
save_and_open_page
を記載すると、スクショがDLできる - Capybaraが使うブラウザは、JavaScript の実行はサポートしていない。JSに依存するテストがある場合は
js: true
というオプションを使う必要がある

7. リクエストスペックで API をテストする P111~
- spec/requests ディレクトリに配置する

8. スペックを DRY に保つ P121~
