前提
本日学んだことを書いていきます。
本題
単体テスト
RSpecをインストール
#省略
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'rspec-rails', '~> 3.8' #追記
gem 'factory_bot_rails', '~> 5.0' #追記
end
# 省略
$ bundle install
Rspec・FactoryBotがインストールされているか確認
$ bundle exec rspec --version
$ bundle exec gem list | grep factory_bot_rails
アプリのプロジェクトにRSpecを導入
$ rails g rspec:install
テスト用のDBを最新の構成にする
$ rails db:migrate:reset RAILS_ENV=test
テスト用のDBとは自動テストを実行するときに利用する専用のDB
例えば自動テストで「全データが消えること」を確認するとき、開発中に利用しているデータが消えてしまっては困る
開発中のデータと自動テスト用のデータを分離して考えることで、双方が干渉しないようになる
モデルのテストコードを追加
$ rails g rspec:model モデル名
テスト実行コマンド
$ bundle exec rspec
RSpecでテストケースを識別するための3つのキーワード
・describe
正常系の機能
大分類のようなイメージで何についてテストをするかを記述する
・context
回答する
中分類のようなイメージで状況を記述する
・it
正しく登録できること
個々のテストケースを表し、期待する振る舞いを記述する
enquete = FoodEnquete.new(
name: '田中 太郎',
mail: 'taro.tanaka@example.com',
age: 25,
food_id: 2,
score: 3,
request: 'おいしかったです。',
present_id: 1
)
# バリデーションが通ること(バリデーションエラーが無いこと)を検証
expect(enquete).to be_valid
※Rails 5.2以降のRSpecではテストコードの実行が終了すると、DBの状態を元に戻してくれる
$ bundle exec rspec spec/models/〜.rb
.
Finished in 0.03355 seconds (files took 2.24 seconds to load)
1 example, 0 failures
実行結果の1行目に記号やアルファベットで結果が表示される
.
成功 テストコードの想定通りに動作した
F
失敗 テストコードの想定通りに操作しなかった
# true/falseのような真偽値を検証する時、be_truthy/be_falseyをマッチャーとする
expect(new_enquete.save).to be_falsey
FactoryBot.define do
factory :food_enquete do
name { '田中 太郎' }
mail { 'taro.tanaka@example.com' }
age { 25 }
food_id { 2 }
score { 3 }
request { 'おいしかったです。' }
present_id { 1 }
end
end
# FactoryBot.build(クラス名)
enquete = FactoryBot.build(:food_enquete)
FactoryBot.create(クラス名)を呼出すと「田中 太郎」のテストデータが作成、さらにテストデータがDBへ保存される
つまり、.saveが不要になる
FactoryBot.create(:food_enquete)
FactoryBot.build(クラス名, 上書きしたい項目: XX)を呼出すと「田中 太郎」のテストデータが作成される
ここでは「お召し上がりになった料理」「満足度」「希望するプレゼント」「ご意見・ご要望」を上書きしている
re_enquete_tanaka = FactoryBot.build(:food_enquete, food_id: 0, score: 1, present_id: 0, request: "スープがぬるかった")
# このテストコードでは、各テストケースの前処理として「田中 太郎」のテストデータを作成する
before do
FactoryBot.create(:food_enquete_tanaka)
end
# インスタンスを共通化してテストデータを作成
let(:new_enquete) { FoodEnquete.new }
共通メソッドのテストコードのファイルを認識させる
モデルのテストコードを書くためのファイルはrails g rspec:model
で準備したが、共通メソッドは手動で用意する
RSpecが手動で作成するテストコードのファイルを認識するように設定を修正する
以下のテストコードのモデルのインスタンスを共通化
まずは修正前のテストコードを確認
# 省略
# コメントアウトを解除する
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
# 省略
共通メソッドのテストコードのファイルを追加
spec/support/concerns/common_modules.rb
にテストコードを追加
共通のテストコードを定義するときはshared_examples
を利用し、その中にテストコードを書く
# 共通のテストコードを呼出すときはit_behaves_likeを利用
it_behaves_like '価格の表示'
統合テスト
capybara
統合テスト(E2E)のフレームワーク
Rspecと連携してWEBブラウザの自動操作を支援する
selenium-webdriver
capybaraを通じてWEBブラウザを自動で操作する
webdrivers
GoogleChromeを操作するドライバ
group :test do
gem 'capybara', '~> 3.28'
gem 'selenium-webdriver', '~> 3.142'
gem 'webdrivers', '~> 4.1'
end
$ bundle install
インストールされているか確認
$ bundle exec gem list | grep -e capybara -e selenium-webdriver -e webdrivers
capybara (3.32.2)
selenium-webdriver (3.142.7)
webdrivers (4.3.0)
spec_helper.rb
の修正
# 省略
require 'capybara/rspec' #追記
RSpec.configure do |config|
# ブラウザにChromeを指定(以下追記)
config.before(:each, type: :system) do
driven_by :selenium, using: :chrome, screen_size: [1280, 960]
end
# 省略
end
※Chromeを1280px × 960pxのウィンドウサイズで開いて操作
追記
--skip-test
デフォルトのテストフレームワークを作成しない
--skip-coffee
CoffeeSprictを使用しない