2019年7月6日土曜日

なんとかWSLで System Spec (System Test) 実行できた (Ruby on Rails 5)

2020/08/21 追記:最初に記事を書いた時とは別のPCで、VcXsrvなしで実行できることを確認しました。(インストールもしていない状態)
環境は以下の通りです。
Windows 10 Home バージョン1909
Ubuntu 18.04.5 LTS (Windows Subsystem for Linux)
Ruby 2.6.5
Rails 6.0.2.2

Minitestでのみ確認しました。RSpecは最近触っておらず…。

2019/08/31追記:結局現在は、VcXsrvもgoogle-chromeも起動させていなくても実行できるようになっています…いつの間にか。
何が影響したのかは分からず…。Windows Updateはありました。(Windows 10 Home, 現在のバージョンは1903)
Ubuntu, Ruby, Rails のバージョンは変わっていません。

2019/07/08訂正:何度もすみません。勘違いがありましたので再度訂正します。

一度VcXsrvは不要と書いたのですが、Headless Chromeを使用する場合でもやはり起動だけはさせておかないといけないようです…。
また、削除しても動いたと思っていた require 'capybara/rspec' require 'webdrivers' の二行が必要でした。
最初に記事を書いた時点からの変更点は以下となります。

  • spec_helper.rb の記載内容
    require 'capybara/rspec' require 'webdrivers' を追加
  • WSLで google-chrome を叩いて、Chromeを起動だけしておく
    → ここで google-chrome --headless --disable-gpu --no-sandbox とすれば
    Errorが出なくなりました。


「Ruby on Rails 5 速習実践ガイド」を見ながらRSpecのテストを実行しようとして詰まりました。
3日くらい試行錯誤してなんとか実行まで漕ぎつけたのでその方法のメモです。

途中から心が折れて解消した手順とかエラーメッセージとか正確に控えてません…ごめんなさい。

また、Minitestのみ使っている別のプロジェクトでSystemTestを実行する方法も並行して調べていたので、情報が混ざっていたらすみません。Capybaraを動かす方法という意味では同じだと思うのですが。

少しでも参考になれば幸いです。

環境

(2020/08/21 更新)
Windows 10 Home バージョン1909
Ubuntu 18.04.5 LTS (Windows Subsystem for Linux)
Ruby 2.6.5
Rails 6.0.2.2

Windows 10
Ubuntu 18.04.1 LTS (Windows Subsystem for Linux)
Ruby 2.5.3
Rails 5.2.1

(Rubyのバージョンは速習実践ガイドでは2.5.1ですが、私は他プロジェクトでもWSLを使用している関係で2.5.3のままにしていたようです…今気が付きました)

解決策

解決に繋がったと思われる設定

  • WSL環境でGUIが使えるよう、VcXsrvをインストールしておく
    昔、下記記事の通りLinux側でRubyMineが使えるようにしようと思ってセットアップしていたのでそれを使いました。(RubyMineは結局Windows側で使っており、VcXsrv自体久しぶりに起動した感じ)
    参考:Windows Subsystem for Linux + VcXsrv + RubyMine でWindowsでも快適なRails開発環境を作ろう - Qiita
    https://qiita.com/fukuramikake/items/283b817c16725af79a28

# spec/spec_helper.rb

require 'capybara/rspec'
require 'selenium-webdriver'
require 'webdrivers'

Selenium::WebDriver::Chrome::Service.driver_path = "/mnt/c/[.exeファイルを配置した
場所へのパス]/chromedriver.exe"

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :selenium_chrome_headless, using: :headless_chrome # headlessでないとうまくいかなかった
  end

...
# Gemfile
group :test do
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  gem 'webdrivers', '~> 4.0' # chromedriver-helper が Deprecated とのことで代わりにこれ

  ...

end

テスト実行時の手順

  1. まずVcXsrvを起動しておく
    • 起動時の設定は
      • One large window
      • Start no client
      • Disable access control チェックボックスをON
        (デフォルトでONのチェックボックスはそのままでOK)
  2. WSLで google-chrome --headless --disable-gpu --no-sandbox を叩いて、Chromeを起動だけしておく
    2019/07/08 変更:コマンドをオプション付きに変更。上記のコマンドで起動することで、headlessのChromeを起動できます。
    WSLのコンソール上は何も表示されないので不安になりますが、これで大丈夫です。
    ※VcXsrvの画面上にも何も表示されません。

  3. WSLをそれとは別にもう1ウィンドウ開き、bundle exec rspec spec/system/tasks_spec.rb (Minitest なら bin/rails test:system) を実行

google-chrome を叩くと、下記のようにVcXsrvのウィンドウにChromeが表示されます。
2019/07/08 訂正: google-chrome--headless オプション付きで起動した場合は何も表示されません。
その状態でテストを実行するとうまくいきました。

google-chrome を叩いたWSLにはいろいろErrorやWarningが出てますがとりあえず動きました…

2019/07/08追記:下記のエラーが出ていましたが、 --headless のオプション付きで叩けば出なくなりました。

$ google-chrome
[16281:16308:0625/013032.168725:ERROR:bus.cc(393)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
[16281:16406:0625/013039.010838:ERROR:bus.cc(393)] Failed to connect to the bus: Could not parse server address: Unknown address type (examples of valid types are "tcp" and on UNIX "unix")

(google-chrome:16281): LIBDBUSMENU-GLIB-WARNING **: 01:30:39.567: Unable to get session bus: Unknown or unsupported transport “disabled” for address “disabled:”
[16325:16325:0625/013044.092177:ERROR:sandbox_linux.cc(368)] InitializeSandbox() called with multiple threads in process gpu-process.
[8:14:0625/013046.117413:ERROR:command_buffer_proxy_impl.cc(126)] ContextResult::kTransientFailure: Failed to send GpuChannelMsg_CreateCommandBuffer.

遭遇したエラーメッセージ

以下、試行錯誤する中で遭遇したエラーメッセージ色々。同じ状況で困っている方がここにたどり着く一助になれば。
(どういう状態でどれが出ていたとか、きちんとメモってません…すみません。)

ChromeDriverの設定周りが怪しいなと思って試行錯誤していたあたり

2019/07/08追記: require 'capybara/rspec' require 'webdrivers' の二行が無い場合もこのエラーになるようです。

Net::ReadTimeout

たぶんLinuxのGUIが関係してるなと思って試行錯誤していたあたり

Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
libGL error: No matching fbConfigs or visuals found
LIBDBUSMENU-GLIB-WARNING Unable to get session bus: Unknown or unsupported transport “disabled” for address “disabled:”

Warningですが

WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead.

メモ

  • headless じゃないChromeはうまくいかなかった(Net::timeout)
    (私のPCのSpecの問題かも)
  • VcXsrvをMultiple windowsの設定で起動するとうまくいかなかった。
    (Multiple Windowsを選択して起動すると、Chromeがウィンドウ上部のアプリ名とアイコンしか表示されず、WSLのコンソールにGUIとかグラフィックカード関連っぽいエラーが出てました)

2019/07/08追記: --headless オプション付きでChromeを起動すればエラーが出ないことから、色々GUI用の設定が足りてないのかもしれません。
とりあえず今は headless chrome が使えればいいのでこれで行きます。

参考にしたURLいろいろ

さすが著者の方ご本人の解説ということでわかりやすかったです。

2019/07/08追記: そもそも最初から --headless オプションを付けて起動すればいいのではというのもこちらを読んでいて気が付きました。ありがとうございます!
「対策B」にあるようにコード内に起動オプションを書く方法では、実行しても「Chromeのプロセスが起動していないようです」というようなエラーがでて失敗するので、先に手動で起動させておくという方法に行きついたのですが、ならそもそも手動で起動する際にこのオプションを付ければheadlessで起動できるんじゃ…と後から気づきました。

2 件のコメント:

  1. はじめまして。
    3日ぐらいErrorで悩んでいて、こちらにたどり着きました。
    自分の設定ミス(ドライバーのPATHを通すのを忘れていた)だったのですが、ばっちり解決しました。
    とても感謝してます! ありがとうございましたm(__)m

    返信削除
    返信
    1. コメントありがとうございます!お役に立ったようで良かったです。

      削除