フィーチャーテスト(Rails + Rspec + Capybara)
追記: コメントをいただきまして、一部内容を更新しています。
今朝、rspec 3.5リリースの記事*1をrspec
の公式HPから確認した所
Rails 5 では、 assigns と assert_template が soft deprecated になりました。
という内容が書いてあり、今までcontroller spec
に書いていたテストの一部をrequest spec
に移すことになりそうです。
controller spec
でテストする内容は、responseとレコードの新規/更新/削除になるのかと思います。
assigns
が使えず*2、インスタンス変数にアクセスできなくなっているため、
controller spec
でテストするのではなく、別のspec
でテストを書くことになりそうです。
本題に戻ります。
自作アプリにフィーチャーテストを追加しまして、まとめていきます。
model, controllerと、poltergeist
の準備についても省いています。
Gemfile
# Gemfile ... group :development, :test do ... gem 'factory_girl_rails' end ... group :development do gem 'capybara' gem 'poltergeist' gem 'launchy' gem 'database_cleaner' # 一部削除しました。 gem 'simplecov', require: false end
simplecov
は、テストカバレッジを見るgem
になるので、外しても良いです。
simplecov
を利用する上で必要な設定は引き続きで、記事にのせています。
利用する場合、html
が作成されますが、rails s
からアクセスできる場所にファイルが保存されないため、
ruby
からwebrick
を起動するスクリプトを書くと使い易くなります。
spec/rails_helper.rb
rails_helperに追加していきます。
# rails_helper.rb ... require 'simplecov' SimpleCov.start('rails') do add_filter '/vendor/' end require 'capybara/rspec' require 'cabtpara/poltergeist' Capybara.javascript_driver = :poltergeist Rspec.configure do |config| ... # sample # RSpec.configure do |c| # c.before(:each) { } # :each 全てのテストスイート中のそれぞれのexampleの前に実行される # c.before(:all) { } # :all それぞれのトップレベルのグループの最初のexampleの前に実行される # c.before(:suite) { } # :suite 全てのspecファイルがロードされたあと、最初のspecが実行される前に一度だけ実行される #end # exampleは、eachのalias # contextは、allのalias # https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example config.before(:suite) do if config.use_transactional_fixtures? raise(<<-MSG) Delete line `config.use_transactional_fixtures = true` from rails_helper.rb (or set it to false) to prevent uncommitted transactions being used in JavaScript-dependent specs. During testing, the app-under-test that the browser driver connects to uses a different database connection to the database connection used by the spec. The app's database connection would not be able to access uncommitted transaction data setup over the spec's database connection. MSG end load Rails.root.join('db', 'seeds.rb') DatabaseCleaner.clean_with, :truncation, { except: %w(master_tables) } end config.before(:each) do DatabaseCleaner.strategy = :transaction end config.before(:each, type: :feature) do driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test if !driver_shares_db_connection_with_specs DatabaseCleaner.strategy = :truncation end end config.before(:each) do DatabaseCleaner.start end config.append_after(:each) do load Rails.root.join('db', 'seeds.rb') DatabaseCleaner.clean end ... config.include LoginMacro end
factories
最低限のfactoryを準備します。
# spec/factories/users.rb FactoryGirl.define do factory :user do email: 'user@example.com' password 'secret' password_confirmation 'secret' end end
spec/support/login_macro.rb
# spec/support/login_macro.rb module LoginMacro ... def sign_in(user) visit admin_sessions_new_path fill_in 'user_email', with: user.email fill_in 'user_password', with: 'secret' click_on 'Submit' end end
spec/support/shared_db_connection.rb
コメントをいただきまして、最新のdatabase_cleanerを利用する場合、不要になっています。
feature
featureテストを追加します。
# spec/features/user_login_spec.rb require 'rails_helper' Rspec.feature 'Authenticate', type: :feature do scenario 'login user', js: true do user = create(:user) sign_in(user) expect(page).to have_content user.company.name end end
追記:
scenario
に追加されているオプションjs: true
により、javascript
を動作させることができます。
テスト実行
$ bundle exec rspec spec/features/admin_login_spec.rb . Finished in 7.05 seconds (files took 2.76 seconds to load) 1 example, 0 failures Coverage report generated for RSpec to /home/user_name/application_name/coverage. 130 / 448 LOC (29.02%) covered.
Coverage...
は、simplecov
が出力するログです。
以上になります。
参考
Feature spec - Feature specs - RSpec Rails - RSpec - Relish
使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」 - Qiita
CentOS6にyumでphantomjs 2.1.1をインストール - Qiita
[Ruby] よく使うRspecのレシピ集(Rspec3.3) | Developers.IO
*1:http://rspec.info/ja/blog/2016/07/rspec-3-5-has-been-released/
*2:gemを入れることで利用することはできるが新規アプリでは非推奨