CapybaraのJSテストがrandom failする

  • 45
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Rspec/Capybarapoltergeistcapybara-webkit を使ってJavascriptを含めたテストを行っている場合にランダムにテストが失敗することがある。(Random fail)

主な原因の一つは

テストの実行中にAjaxを発生させてAjaxが完了する前にテストが終了し次のテストが同じDBを参照しようとした時に起こる。

この問題の一つの解決策は

Ajaxが終了していることをテストの最後に確認すること。
THOUGHTBOT, INC. の記事に一つの解決策を紹介している。

http://robots.thoughtbot.com/automatically-wait-for-ajax-with-capybara

ソースコードはこちら

# spec/support/wait_for_ajax.rb
module WaitForAjax
  def wait_for_ajax
    Timeout.timeout(Capybara.default_wait_time) do
      loop until finished_all_ajax_requests?
    end
  end

  def finished_all_ajax_requests?
    page.evaluate_script('jQuery.active').zero?
  end
end

RSpec.configure do |config|
  config.include WaitForAjax, type: :feature
end

それに加えて以下の行を追加した。

RSpec.configure do |config|
  config.include WaitForAjax, type: :feature
+  config.after(:each, js: :true) { wait_for_ajax }
end

js: trueを指定している各specの終了後にAjaxが終了していることを確認する。
上記を追加することで最低限、spec間のコネクションの張りっぱなしによるDBエラーの問題は解決出来る。
jQuery.active で実行中のAjaxの数を取得することが出来る。Documentにはあまり大きくかかれてないmethodらしい。

各行でajaxを待ちたい時は

  • wait_for_ajax をspecの中で呼ぶ

これでJavascriptが原因で起こるほとんどのrandom failを解決できた。