環境
Amazon Linux AMI release 2018.03
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
Rails 5.1.7
rspec-rails 3.8.2
capybara 3.29.0
factory_bot_rails 5.0.2
selenium-webdriver 3.142.4
前提・実現したいこと
Railsチュートリアル(第四版)の2週目を進めている最中で、テストにはRSpecを使用しています。
過去にチュートリアルではRSpecを使っていた(第二版)ので、参考がてら時々そちらも見ています。
8章を終えて、テストを実行するとファイル指定の時のみなぜかテストが失敗してしまいます。
調べてみても解決できなかったため、ご教示ください。
発生している問題・エラーメッセージ
フォルダを指定して、テストを一括で実行すると全部通ります。
$ bundle exec rspec spec ....................................................... Finished in 11.02 seconds (files took 1.97 seconds to load) 55 examples, 0 failures
しかし、あるファイルspec/system/sessions_spec.rb
を指定してテストを実行すると失敗します。
他のファイルも指定して実行したのですが、こちらの方は全部成功しました。つまり、sessions_spec.rb
の時のみ失敗するようです。
ソースコードをコメントアウトして一括テストしてみるとexamplesの数が減っていたので、ちゃんと拾えてはいると考えています。
$ bundle exec rspec spec/system/sessions_spec.rb FFFFFFFFF Failures: 1) Authentication signin page Failure/Error: before { visit login_path } NameError: undefined local variable or method `login_path' for #<RSpec::ExampleGroups::Authentication::SigninPage:0x0000000001abd168> # ./spec/system/sessions_spec.rb:8:in `block (3 levels) in <top (required)>' (~略~)
後述するソースコードのvisit login_path
をvisit '/login'
に書き換えたところ、やはりファイル指定の場合のみテストが失敗し、次のようなエラーコードが出ました。
それからArgumentError: rack-test requires a rack application, but none was given
について調べてみたのですが、結局解決できず質問させていただく形となりました。
$ bundle exec rspec spec/system/sessions_spec.rb FFFFFFFFF Failures: 1) Authentication signin page Got 0 failures and 2 other errors: 1.1) Failure/Error: before { visit '/login' } ArgumentError: rack-test requires a rack application, but none was given # /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/capybara-3.29.0/lib/capybara/rack_test/driver.rb:18:in `initialize' # /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/capybara-3.29.0/lib/capybara/registrations/drivers.rb:4:in `new' # /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/capybara-3.29.0/lib/capybara/registrations/drivers.rb:4:in `block in <top (required)>' # /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/capybara-3.29.0/lib/capybara/session.rb:102:in `driver' # /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/capybara-3.29.0/lib/capybara/session.rb:276:in `visit' # /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/capybara-3.29.0/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>' # ./spec/system/sessions_spec.rb:8:in `block (3 levels) in <top (required)>' (~略~)
該当のソースコード
config/routes.rb
Ruby
1Rails.application.routes.draw do 2 3 ~(略)~ 4 5 # Sessions 6 get '/login', to: 'sessions#new' 7 post '/login', to: 'sessions#create' 8 delete '/logout', to: 'sessions#destroy' 9end
spec/rails_spec.rb
Ruby
1require 'capybara/rspec' 2 3RSpec.configure do |config| 4 5 config.before(:each, type: :system) do 6 driven_by :selenium_chrome_headless 7 end 8 9 config.include Capybara::DSL 10 config.expect_with :rspec do |expectations| 11 expectations.include_chain_clauses_in_custom_matcher_descriptions = true 12 end 13 14 config.mock_with :rspec do |mocks| 15 mocks.verify_partial_doubles = true 16 end 17 18 config.shared_context_metadata_behavior = :apply_to_host_groups 19 20end 21
app/controllers/sessions_controller.rb
Ruby
1class SessionsController < ApplicationController 2 def new 3 end 4 5 def create 6 user = User.find_by(email: params[:session][:email].downcase) 7 if user && user.authenticate(params[:session][:password]) 8 log_in(user) 9 redirect_to user 10 else 11 flash.now[:danger] = 'Invalid email/password combination' 12 render 'new' 13 end 14 end 15 16 def destroy 17 log_out 18 redirect_to root_url 19 end 20end
spec/system/sessions_spec.rb
Ruby
1require 'spec_helper' 2 3describe "Authentication" do 4 5 subject { page } 6 7 describe "signin page" do 8 before { visit '/login' } 9 10 it { should have_title('Log in') } 11 it { should have_content('Log in') } 12 end 13 14 describe "login" do 15 before { visit login_path } 16 17 context "with invalid information" do 18 before { click_button('Log in') } 19 20 it { should have_title('Log in') } 21 it { should have_selector('div.alert.alert-danger', text: 'Invalid') } 22 23 context "when reload" do 24 before { visit login_path } 25 26 it { should_not have_selector('div.alert.alert-danger', text: 'Invalid') } 27 end 28 ~(略)~ 29 end 30 end 31end

回答1件
あなたの回答
tips
プレビュー