vdeep

*

vdeepはプログラミング、IT、Web技術、ライフハックの事などなどを管理人okutaniがつぶやくブログです

【Rails】『RSpec + FactoryBot + Capybara + Webdrivers』の導入&初期設定からテストの書き方まで

   

LINEで送る
Pocket


こんにちは、okutani(@okutani_t)です。本記事では、Ruby on Railsに『RSpec』『FactoryBot(旧FactoryGirl)』『Capybara』『Webdrivers』を導入する方法から初期設定、動作確認ていどのかんたんなテストの書き方までを解説しています。

RSpec, FactoryBot, Capybara, Webdriversのそれぞれの役割は以下のとおりです。

  • RSpec:Rubyで使えるテストフレームワーク
  • FactoryBot:テストデータを作成
  • Capybara:フィーチャーテスト(E2Eテスト・ブラウザテストとも呼ばれる)をRubyでおこなうためのフレームワーク
  • Webdrivers:ChromeDriverをかんたんに導入してくれるgem

今回使用するツールのバージョンは以下のとおりです。

  • Ruby 2.6.2
  • Rails 5.2.3
  • RSpec 3.8.2
  • FactoryBot 5.0.2
  • Capybara 3.25.0
  • Webdrivers 4.0.1

また、以下のテストを、かんたんなサンプルを交えて紹介しています。

  • Model Spec
  • System Spec
  • Request Spec

今回利用しているgemのGitHubのリポジトリはこちら。

LINKrspec/rspec-rails: RSpec for Rails-3+

LINKthoughtbot/factory_bot: A library for setting up Ruby objects as test data.

LINKteamcapybara/capybara: Acceptance test framework for web applications

LINKtitusfortner/webdrivers: Keep your Selenium WebDrivers updated automatically

それでは、実際に導入方法から、テストの書き方までみていきましょう。

スポンサーリンク

導入

プロジェクトのGemfileに以下を記述します。すでに対応するgroupが存在するかと思うので、そこにgemを追記してください。

group :development, :test do
  gem 'rspec-rails'
  gem 'factory_bot_rails'
end
group :test do
  gem 'capybara'
  # gem 'selenium-webdriver'
  # gem 'chromedriver-helper'
  gem 'webdrivers'
end

もしここで「chromedriver-helper」「selenium-webdriver」が記述されていたら、「Webdrivers」で代替できるので削除しましょう。

bundle installを実行。今回はプロジェクト直下に配置します。

$ bundle install --path vendor/bundle

RSpecが導入できたか確認。

$ bundle exec rspec --version
RSpec 3.8

RSpec3.8が導入されていることが確認できました。

それでは、RSpecの初期設定からおこなっていきましょう。

RSpecの初期設定

RSpecの初期設定ファイルをgenerateします。以下のコマンドを実行。

$ bundle exec rails generate rspec:install

以下のファイルが生成されます。

  • .rspec
  • spec/
  • spec/spec_helper.rb
  • spec/rails_helper.rb

ちなみに、Railsのデフォルトで配置されているtestディレクトリはもう使わないので破棄してOKです。

$ rm -rf test

もし、すでにMiniTest等でテストを書いていたらrspecに移行させてから削除しましょう。

今後は「spec/」以下にテストファイルを配置していきます。

また、今後はモデルやコントローラーを生成すると、自動でspecディレクトリにテストファイルが生成されます。

すでに作成されているモデルやコントローラーに対して、テストファイルを作成することもできます。

specファイルの自動生成設定

「config/application.rb」にrspecの設定を記述することで、rails generate時に自動生成するspecファイルを制御することができます。

module アプリ名
  class Application < Rails::Application
    # ...省略...
    config.generators do |g|
      g.test_framework :rspec,
                       view_specs: false,
                       helper_specs: false,
                       controller_specs: false,
                       routing_specs: false,
                       request_specs: false
    end
  end
end

私は上記のように設定して、viewやcontrollerなどのspecファイルは自動生成しないように設定しました。

上記は適宜お好みで設定してみてください。

出力結果を見やすくする

「.rspec」の内容を以下のようにすることで、実行結果を見やすくすることができます。

--require spec_helper
--format documentation

・before

・after

こちらもお好みで設定してみてください。

FactoryBotの初期設定

テストデータを生成するFactoryBotの初期設定をおこないます。

「spec/rails_helper.rb」に以下を追記。

RSpec.configure do |config|
  # ...省略...
  config.include FactoryBot::Syntax::Methods # 追加
end

これで、FactoryBotを使うときに接頭語からFactoryBotを取り除いてすっきり書くことができます。

例)

FactoryBot.create(:user)
↓
create(:user)

「FactoryBot.create(:user)」のように接頭語付きで使う場合、上記の設定は不要です。

それでは、実際にModelのテストを書いてみます。

Model Specの実装例

もし、すでにUserモデルが存在していて、specファイルが存在しない場合は以下のコマンドでテストファイルを生成します。

$ bundle exec rails g rspec:model user

今回は以下のファイルが生成されました。

  • spec/models/user_spec.rb
  • spec/factories/users.rb

今回はFactoryBotも同時に導入しているので、「spec/factories/users.rb」も同時に生成されました。

ちなみに、ファクトリーファイルのみを生成したい場合、以下のようにも実行できるので覚えておきましょう。

$ bundle exec rails g factory_bot:model user

生成された「spec/models/user_spec.rb」の中身は以下のとおりです。

require 'rails_helper'

RSpec.describe User, type: :model do
  pending "add some examples to (or delete) #{__FILE__}"
end

「spec/factories/users.rb」の中は以下のとおり。

FactoryBot.define do
  factory :user do
    
  end
end

今回、これらのファイルを以下のように書き換えてみました。

  • 「spec/models/user_spec.rb」
require 'rails_helper'

RSpec.describe User, type: :model do
  it 'is valid' do
    user = build(:user)
    expect(user).to be_valid
  end
end
  • 「spec/factories/users.rb」
FactoryBot.define do
  factory :user do
    name { 'okutani' }
    sequence(:email) { |n| "okutani#{n}@example.com" }
    password { '1234abcd' }
    password_confirmation { '1234abcd' }
    confirmed_at { Time.current }
  end
end

上記は、Devise gemで作成したUserモデルのテストデータをFactoryBotで生成し、Model Specでバリデーションのテストをおこなった例です。

実際に、Userモデルにバリデーションを追加したり外したりしてみて、挙動を確かめてみると良いですね。

では、実際にテストの実行をおこなってみます。

テスト用DBのマイグレーション

テストをおこなう前に、テスト用DBをマイグレーションしておきましょう。

以下のコマンドを実行。

$ bundle exec rails db:migrate RAILS_ENV=test

これでテスト用DBがmigrateされました。

テストの実行

以下のコマンドでテスト全体を実行できます。

$ bundle exec rails rspec spec

特定のファイルのみを実行したい場合は以下。

$ bundle exec rspec spec/models/user_spec.rb

また、次のように行数を指定することで、その行に含まれるテストのみを実行してくれます。

$ bundle exec rspec spec/models/user_spec.rb:5

これでRails + RSpecでテスト開発をおこなうことができますね。

Capybaraの初期設定

次に、System Specを利用するため、Capybaraの初期設定をおこないます。

以下のコマンドでCapybaraの設定ファイルを追加します。

$ mkdir spec/supports
$ touch spec/supports/capybara.rb

今回は「spec/supports/capybara.rb」を以下のように実装しました。

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :selenium_chrome_headless
  end
end

「spec/spec_helper.rb」に以下の行を記述し、作成した設定ファイルを読み込みます。

require 'supports/capybara'

これでSystem Specの実行時に「Headless Chrome」が利用されるようになり、テスト実行時にブラウザが立ち上がらないようになります。

System Specの実装例

Capybaraの設定が済んだので、実際にSystem Specを実装していきます(System SpecはRSpec 3.7、Rails 5.1以降で利用できます)。

以下のコマンドを実行して System Specの実行ファイルを作成。

$ mkdir spec/system
$ touch spec/system/home_spec.rb

以下のように実装してみました。

require 'rails_helper'

RSpec.feature 'Home', type: :system do
  scenario 'shows greeting' do
    visit root_path
    expect(page).to have_content 'Hello World!'
  end
end

テストを実行します。

$ bundle exec rails rspec spec

これでテストを実行し、TOPページに「Hello World!」という文字列が存在すれば、テストが成功します。

Request Specの実装例

次にRequest Specの実装例について見ていきましょう。

Rails 5.0からControllerテストは非推奨になったので、代わりにRequest Specを実装していきます。

Request Specでは以下の項目をテストします。

  • リクエストに対して適切なステータスコード(200, 302など)が返ってくるか
  • リターンされたビュー(もしくはJSONデータ)に想定したデータが含まれているか
  • 適切にDBにデータが反映されているか
  • リダイレクト処理がある場合、正しくリダイレクトされたかなど

本記事では、必要最低限動くところまでしか解説していないため、Request Specで行うべきテスト項目について詳しく知りたい場合は「rails request spec」などで調べてみてください(以下に参考になる記事を紹介しておきます)。

参考Rails5でコントローラのテストをController specからRequest specに移行する - Qiita

それでは一例として、TOPページが正しく表示されていることを確認するRequest Specを実装してみます。

以下のコマンドを実行して雛形ファイルを作成します。

$ bundle exec rails g rspec:request home

「spec/requests/homes_spec.rb」が作成されました。今回TOPページは1枚だけなので、ファイル名、ファイル内のhomesをhomeに置換して進めています。

「spec/requests/home_spec.rb」を以下のように実装しました。

require 'rails_helper'

RSpec.describe 'Home', type: :request do
  describe 'GET #index' do
    it 'responds successfully' do
      get root_path
      expect(response).to have_http_status(200)
      expect(response.body).to include 'Hello World!'
    end
  end
end

これでhome_controllerが存在していて、かつ正しくアクセスでき、viewに「Hello World!」が含まれていればテストが成功します。

今回は、response.bodyに'Hello World!'が含まれているかどうか確認しましたが、System Specの実装例のようにhave_contentを利用してもOKです。お好みで実装してみてください。

まとめ

かんたんではありましたが、RSpecの導入&初期設定、一通りのテスト実装までを解説しました。

他にも、Helper Spec, Service Specなどを記述していけば、一通りのテストが網羅できることになりますね。

詳しいテストの実装方法については、時間があるとき別記事にまとめようと思います。

RailsでRSpecを利用する方の参考になれば幸いです。

LINEで送る
Pocket

okutani (okutani_t) のヒトコト
テストはあまり重要には見えませんが、サービスを運用していく上でほぼ必須と言えますね。それなりに学習コストが必要なので、しっかり勉強していきましょう!

Web開発のお仕事を募集しています

フリーランスのエンジニアとして、Webシステム開発のお仕事依頼を随時募集しています(現在の業務量によってお受けできない場合もあります)。

Ruby on Rails」「JavaScript(jQuery, Reactなど)」「HTML + CSS」を用いたシステム開発、「Heroku」等を用いたサーバー構築・運用、「Git」や「GitHub」を利用したソーシャルコーディングなどに対応しています。

ご依頼を検討している方は、下記リンク本ブログからのお問い合わせ、もしくはokutaniのポートフォリオからご連絡ください。

LINKお問い合わせ

LINKokutani's Portfolio


 - Ruby on Rails

スポンサーリンク

PC用AdSense

PC用AdSense

  こちらもどうぞ

vdeepのトップページへ戻る画像です。風船の形をした島を女の子が掴んでいます。