開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina
前提
こちらが出来ている前提で進めます。
【Ruby on Rails】RSpec導入まで
モデルのテストはこちら
【Ruby on Rails】RSpecでのモデルテスト
コントローラーのテストはこちら
【Ruby on Rails】RSpecでのコントローラーテスト
viewのテスト準備
##・ファイルの作成
①
spec配下にsystemフォルダとfactoriesフォルダを作成。
systemフォルダには、テストしたいviewのファイルも作成し、
factoriesフォルダにはダミーデータのモデルを作成します。
今回はpostのviewをテストするため、
下記のようなファイル構成にします。
spec/system/post_spec.rb
→テストしたい内容を記述します。
spec/factories/post.rb
spec/factories/user.rb
→ダミーデータを作成します。
②
FactoryBotを使えるようにします。
使用するとuser = create(:user) のようにDB登録やモデルのビルドができるため便利です。
spec配下にsupportフォルダとfactory_bot.rbファイルを作成し、下記のように記述します。
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
その後、下記を追加します。
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
require 'support/factory_bot' # <ーーー 追加
...
spec_helper.rbの編集
下記内容をRSpec.configure do |config|内に追加します。
RSpec.configure do |config|
config.before(:each, type: :system) do
driven_by :rack_test
end
...
end
実際のコード
まずはダミーデータを作成します。
FactoryBot.define do
factory :user do
email { Faker::Internet.email }
phone_number { 12345678909 }
password { 'password' }
password_confirmation { 'password' }
end
end
FactoryBot.define do
factory :post do
body { Faker::Lorem.characters(number:20) }
user
end
end
次にテストコードを記述します。
require 'rails_helper'
describe '投稿のテスト' do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:post) { create(:post, user: user) }
let(:post2) { create(:post, user: user2) }
before do
visit new_user_session_path
fill_in 'user[email]', with: user.email
fill_in 'user[password]', with: user.password
click_button 'ログイン'
visit user_posts_path(user, post)
end
describe '表示のテスト' do
context '新規投稿画面' do
before do
visit new_user_post_path(user, post)
end
it 'bodyフォームが表示される' do
expect(page).to have_field 'post[body]'
end
it '新規投稿ボタンが表示される' do
expect(page).to have_button '新規投稿'
end
end
end
describe '編集のテスト' do
context '自分の投稿の編集画面への遷移' do
it '遷移できる' do
visit edit_user_post_path(user, post)
expect(current_path).to eq('/users/' + user.id.to_s + '/posts/' + post.id.to_s + '/edit')
end
end
context '他人の投稿の編集画面への遷移' do
it '遷移できない' do
visit edit_user_post_path(user, post2)
expect(current_path).to eq('/users/' + user.id.to_s + '/posts')
end
end
end
end
その後、ターミナルで下記を実行してください。
$ rspec spec/requests
エラーが出る場合はこちらも試してみてください
$ bundle exec rspec spec/system --format documentation
テストを通過すると
Finished in 3.64 seconds (files took 2.75 seconds to load)
4 examples, 0 failures
このように表示されるためテスト内容が正しいことを表しています。
参考(モデルのテストから抜粋)
【Ruby on Rails】RSpecでのモデルテスト
逆にテストを通過しない場合、このような形でどこでエラーが起きているかわかるので、
テストコードが間違っているのか、バリデーションが間違っているかなどがわかるようになります。
Failures:
1) Postモデルのテスト バリデーションのテスト titleカラム 20文字以下であること
Failure/Error: let!(:post) { build(:post) }
NoMethodError:
undefined method `build' for #<RSpec::ExampleGroups::Post::Nested::Title:0x000000000619e938>
# ./spec/models/post_spec.rb:9:in `block (3 levels) in <top (required)>'
2) Postモデルのテスト バリデーションのテスト titleカラム 空欄でないこと
Failure/Error: let!(:post) { build(:post) }
NoMethodError:
undefined method `build' for #<RSpec::ExampleGroups::Post::Nested::Title:0x0000000007491518>
# ./spec/models/post_spec.rb:9:in `block (3 levels) in <top (required)>'
Finished in 0.07992 seconds (files took 2.41 seconds to load)
2 examples, 2 failures
Failed examples:
rspec ./spec/models/post_spec.rb:11 # Postモデルのテスト バリデーションのテスト titleカラム 20文字以下であること
rspec ./spec/models/post_spec.rb:15 # Postモデルのテスト バリデーションのテスト titleカラム 空欄でないこと
また下部にあるrspec ./spec/models/post_spec.rb:11を使い、
下記のように個別にテスト内容を確認することも出来ます。
$ rspec spec/models/post_spec.rb:11
まとめ
今回は
まずはダミーデータを作成し、
ログイン画面で実際にログインをした後、
1,ログインした状態で投稿画面にいき、表示が正しくされているか
2,他人の投稿画面に遷移できないか
この2点をテストしました。
javascriptのテストをする方法もあるため
興味のある方は調べてみてください。
またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork