質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.21%

『Ruby on Rails 5 速習実践ガイド』のRSpecの実行部分でテストが通らなく詰まっています。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 1,087

前提・実現したいこと

RSpecのテストを通るようにしたいです。

環境
-OS: Ubuntu 18.04.1 LTS (WSL windows10
-Rails 5.2.3

Ubuntu環境にChromeが必要そうだったのでChromeとChromeDriverをインストールしました。

usr@desktop@@@@:~/taskleaf$ google-chrome -version
=> Google Chrome 74.0.3729.131

usr@desktop@@@@:~/taskleaf$ google-chrome
=> [337:337:0502/140113.683623:ERROR:browser_dm_token_storage_linux.cc(101)] 
   Error: /etc/machine-id contains 0 characters (32 were expected).
   (google-chrome:488): Gtk-WARNING **: 14:06:56.681: cannot open display:

usr@desktop@@@@:~/taskleaf$ chromedriver -v
=> ChromeDriver 74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29})

usr@desktop@@@@:~/taskleaf$ chromedrivers
=> Starting ChromeDriver 74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}) on port 9515
   Only local connections are allowed.
   Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
..省略

webdrivers (3.8.0)
webrick (default: 1.4.2)
websocket-driver (0.7.0)
websocket-extensions (0.1.3)
xmlrpc (0.3.0)
xpath (3.2.0)
zlib (default: 1.0.0)

現場で使える Ruby on Rails 5速習実践ガイドの205ページで止まっている状況です。

発生している問題・エラーメッセージ

一番最初に発生したエラー

 Failures:

 1) タスク管理機能 一覧表示機能 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される
    Got 0 failures and 2 other errors:

 1.1) Failure/Error: visit login_path

      Selenium::WebDriver::Error::WebDriverError:
        unable to connect to chromedriver 127.0.0.1:9515



      # ./spec/system/tasks_spec.rb:14:in `block (4 levels) in <top (required)>'

 1.2) Failure/Error: raise Error::WebDriverError, cannot_connect_error_text

      Selenium::WebDriver::Error::WebDriverError:
        unable to connect to chromedriver 127.0.0.1:9515


次に発生したエラー
https://qiita.com/jnchito/items/f9c3be449fd164176efa
chromedriver-helperというgemのサポートが終了したのでwebdriversというgemに移行することが推奨されているということなので

gem uninstall chromedriver-helper
Gemfileにwebdriversを追記
Gemfileのchromedriver-helperを削除
bundle install

の手順を実行。

Failures:

1) タスク管理機能 一覧表示機能 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される
    Got 0 failures and 2 other errors:

 1.1) Failure/Error: visit login_path

      NoMethodError:
        undefined method `strip' for nil:NilClass



      # ./spec/system/tasks_spec.rb:14:in `block (4 levels) in <top (required)>'

 1.2) Failure/Error: `#{executable} --product-version`.strip

      NoMethodError:
        undefined method `strip' for nil:NilClass

現在発生しているエラー
そもそもChromeが入っていないからエラーになるんじゃないか?
と感じて、ubuntuにChromeをインストールしました。よくわからないのでChromeDriverもインストールしました。

bundle exec rspec spec/system/tasks_spec.rb

Capybara starting Puma...
* Version 3.12.1 , codename: Llamas in Pajamas
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:51578
F

Failures:

  1) タスク管理機能 一覧表示機能 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される
     Got 0 failures and 2 other errors:

     1.1) Failure/Error: visit login_path

          Net::ReadTimeout:
            Net::ReadTimeout



          # ./spec/system/tasks_spec.rb:15:in `block (4 levels) in <top (required)>'

     1.2) Failure/Error: @io.to_io.wait_readable(@read_timeout) or raise Net::ReadTimeout

          Net::ReadTimeout:
            Net::ReadTimeout

          |
          |省略
          |

          Finished in 2 minutes 14.3 seconds (files took 3.07 seconds to load)
          1 example, 1 failure

          Failed examples:

          rspec ./spec/system/tasks_spec.rb:21 # タスク管理機能 一覧表示機能 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される

/home/user/.rbenv/versions/2.5.1/lib/ruby/2.5.0/net/http.rb:939:in `rescue in block in connect': Failed to open TCP connection to 127.0.0.1:9515 (Connection refused - connect(2) for "127.0.0.1" port 9515) (Errno::ECONNREFUSED)

該当のソースコード

spec/rails_helper.rb

require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
begin
  ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
  puts e.to_s.strip
  exit 1
end
RSpec.configure do |config|

        # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = true

  # RSpec Rails can automatically mix in different behaviours to your tests
  # based on their file location, for example enabling you to call `get` and
  # `post` in specs under `spec/controllers`.
  #
  # You can disable this behaviour by removing the line below, and instead
  # explicitly tag your specs with their type, e.g.:
  #
  #     RSpec.describe UsersController, :type => :controller do
  #       # ...
  #     end
  #
  # The different available types are documented in the features, such as in
  # https://relishapp.com/rspec/rspec-rails/docs
  config.infer_spec_type_from_file_location!

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
  # arbitrary gems may also be filtered via:
  # config.filter_gems_from_backtrace("gem name")
end


spec/spec_helper.rb

require 'capybara/rspec'

RSpec.configure do |config|

  config.before(:each, type: :system) do
    driven_by :selenium_chrome_headless
  end
  # rspec-expectations config goes here. You can use an alternate
  # assertion/expectation library such as wrong or the stdlib/minitest
  # assertions if you prefer.
  config.expect_with :rspec do |expectations|
    # This option will default to `true` in RSpec 4. It makes the `description`
    # and `failure_message` of custom matchers include text for helper methods
    # defined using `chain`, e.g.:
    #     be_bigger_than(2).and_smaller_than(4).description
    #     # => "be bigger than 2 and smaller than 4"
    # ...rather than:
    #     # => "be bigger than 2"
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  # rspec-mocks config goes here. You can use an alternate test double
  # library (such as bogus or mocha) by changing the `mock_with` option here.
  config.mock_with :rspec do |mocks|
    # Prevents you from mocking or stubbing a method that does not exist on
    # a real object. This is generally recommended, and will default to
    # `true` in RSpec 4.
    mocks.verify_partial_doubles = true
  end

  # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
  # have no way to turn it off -- the option exists only for backwards
  # compatibility in RSpec 3). It causes shared context metadata to be
  # inherited by the metadata hash of host groups and examples, rather than
  # triggering implicit auto-inclusion in groups with matching metadata.
  config.shared_context_metadata_behavior = :apply_to_host_groups


spec/system/tasks_spec.rb

require 'rails_helper'


describe 'タスク管理機能', type: :system do

  describe '一覧表示機能' do
    before do
      user_a = FactoryBot.create(:user, name: 'ユーザーA', email: 'a@example.com')
      FactoryBot.create(:task, name: '最初のタスク', user: user_a)
    end

    context 'ユーザーAがログインしているとき' do

      before do
        visit login_path
        fill_in 'メールアドレス', with: 'a@example.com'
        fill_in 'パスワード', with: 'password'
        click_button 'ログインする'
      end

      it 'ユーザーAが作成したタスクが表示される' do
        expect(page).to have_content '最初のタスク'
      end

    end
  end
end

関係ありそうな情報

https://qiita.com/jnchito/items/f9c3be449fd164176efa
https://github.com/titusfortner/webdrivers/blob/master/lib/webdrivers/chromedriver.rb
https://github.com/titusfortner/webdrivers/issues/67

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+3

著者の松本です。WSL環境に対する考慮が漏れていて申し訳ないです…。

最初のエラーでは、お察しの通りchromedriverから参照できるchromeが見えていないのが原因かと思います。
Ubuntuにchromeを入れたのに Connection refused になるのは、chromedriver-helper がうまく起動していないためかもしれません。

以下のコマンドを実行してみるとどうなるでしょうか?

bundle exec chromedriver-helper&
bundle exec rspec

もしこれで通らない場合、下記リンクのように、WSLからWindowsのchromedriverを参照するよう設定する方法も試してみてください。

https://gist.github.com/upinetree/fb71a947cc100e7918b7b280485d620c#対策a-chromedriver-helper-を使わずに自分で-chromedriver-を設定する

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/06 00:12

    なるほどです。
    一度はパスしていたのですよね…となると、実行する中で環境の何らかの状態(メモリとか)が変化して、という可能性もありますね。

    ↓の記事のように、タスクマネージャに chromedriver がたくさん残っているようなことはないでしょうか?

    https://boukenki.info/selenium-webdriver-exception-unknown-error-session-deleted-because-of-page-crash-from-tab-crashed-kaiketsu-houhou/

    また、↓の回答ではChromeの起動オプションを変更すると改善するかも?と紹介されていますね。

    https://stackoverflow.com/questions/53902507/unknown-error-session-deleted-because-of-page-crash-from-unknown-error-cannot

    起動オプションを変更する方法は先日紹介したGistの `対策B` に書いてあるので、参照してみてください。

    > これはもう一度スキップしたほうがいいんでしょうか…?

    書籍の進め方という意味ですよね。
    モチベーション的にもつらい状況だと思いますので、一度テストがパスしていることを確認できていますし、学習としてはスキップして次に進んでしまっても良いと思います…!

    キャンセル

  • 2019/05/06 02:57

    >↓の記事のように、タスクマネージャに chromedriver がたくさん残っているようなことはないでしょうか?

    タスクマネージャーを確認したところ怪しいプロセスがいくつもあったので終了させました。
    その後にテストを実行したところ問題なくパスすることが出来ました!
    無事に5章を終わらせることが出来ました。
    今後、また同じようなエラーが発生した場合はタスクマネージャーを確認したいと思います。

    少ない情報しか提供できていないのに、迅速かつ的確に対応していただき感謝します。

    キャンセル

  • 2019/05/06 23:43

    プロセス自動的に終了しないのは結構罠ですね…無事に動くようになってよかったです!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる