Capybaraを使う際に知っておきたいこと


基本的な設定方法や使用方法は書いていません。CapybaraのREADMEを読みましょう。

Driverはどれ使えばいいのか

(参照: READMEs Drivers section)

種類としては以下の3種類のDriverがあります

Driver名 JSが実行出来るか 外部HTTP通信が出来るか headlessかどうか
RackTest N N Y
Selenium Y Y N
Capybara-webkit, Poltergeist Y Y Y

defaultは?

defaultではRackTestが使用されていて、高速だしRubyで書かれているのでRuby以外に依存してるソフトウェアが無くて良いのですが、JSが実行出来ませんし外部APIとかも叩けません。

個人的な意見としてはJS実行、外部APIを叩くことが必要でなければRackTestのままでいいと思います。

JS実行や外部APIを叩きたければ?

こうなるとheadlessではないSelenuimか、headless driverであるCapybara-webkitやPoltergeistになってきます。

まず、headlessではないdriverを選んでしまうとテスト実行毎にブラウザが立ち上がってしまいます。これは鬱陶しいのでメインで使うには不適当です。

ということでheadless driverであるCapybara-webkitやPoltergeistになってきます。
最近まではCapybara-webkitを使うのが多かった気がするのですが、最近はPoltergeistを採用するケースが多い気がします。

理由としては、GitHubの社員が自社内で使用してると思われるRailsアプリのPRの中で言ってる通り、

  • QT, xvfbに依存していない
  • 安定している
  • 開発がより盛ん
  • より速い

特にQTに依存していないというのは個人的に大きいと思っていて、これのお陰でCI上での実行のしやすがあがりますし、
QTをコンパイルする時間がなくなるのでビルド全体の時間も短縮されます。

下で説明しますがheadlessなのにinspectorも起動出来たり、機能も豊富なのも良いですね。

デバッグのやりかた

ここからは基本的にPoltergeist driverを使用してること前提に話します。

僕が今までcapybaraのテストを書いていて困った事は主に2つあって、

  1. 動作の書き方がわからない(e.x. どういうコードを書いたら特定のボタンが押せるのか
  2. テスト上で実行した時だけ機能の挙動が違う

でした、1.は基本的にググって実際に書いてみてやり方を見つけるしかないです。

2.は厄介でして、これは基本的にテスト環境だと違う値のもの(定数だったり設定の値)が影響を及ぼして結果的に違う挙動を引き起こしてることが多いです。

どの値のものが影響を与えてるかは、挙動元のコードを辿ってみていくしか無い気がします。
たどっていう過程で以下の欲求が出てくると思います、それぞれ方法を説明します。

  • ある状態での画面の状態を知りたい
  • JS側のデバッグをしたい

ある状態での画面の状態が知りたい

headless driverを使用しているのでボタンを押した後状態とかテストを実行してるだけでは中々分かりにくいです

例えば以下の様なテストがあったとして

describe 'Sign up feature' do
  it 'works' do
    visit root_path
    click_on 'Sign up'
    click_on 'hoge'
  end
end

よく起こるのが

  • "Sign up"押したら、
  • root_pathから新規登録ページに飛んで、
  • 新規登録ページにある"hoge"をクリックしたいのに、
  • "hoge"が見つかりませんとエラーが出る

みたいなケースです。headless driverを使ってるのでSign upをクリックしたあと起こってることが分かりにくいです。

そんな時は以下のようにしてスクリーンショットを撮りましょう

 
    visit root_path
    click_on 'Sign up'
    page.save_screenshot('/path/to/file.png')
    click_on 'hoge'
  end
end

page.save_screenshotの説明はここ

JS側のデバッグをしたい

サーバー側のデバッグは普通にpryを使用したbinding.pry等でデバッグが可能なのですが、JSはそうにもいきません。

ただJS側でデバッグしたいことは起こるのでそういう時はPoltergeistが提供しているRemote debugging機能を使用します。

この機能を使うには、先ほどのリンクにも記載されてる通り、driverを設定する際、

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app)
end

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app, inspector: true)
end

に変えるだけで出来ます。

これによって、例えば先ほどのテストで、以下のように書けば

describe 'Sign up feature' do
  it 'works' do
    visit root_path
    page.driver.debug
    click_on 'Sign up'
    click_on 'hoge'
  end
end

page.driver.debugの時点で以下のようにwebkit inspectorが起動し、"Elements"でhtml DOMを確認したり、"Console"でJSを実行したり出来ます。

普段ブラウザ上で行ってるデバッグが可能になります、headless browserなのに :)