Rspec/Capybara で poltergeist や capybara-webkit を使ってJavascriptを含めたテストを行っている場合にランダムにテストが失敗することがある。(Random fail)
###主な原因の一つは
テストの実行中にAjaxを発生させてAjaxが完了する前にテストが終了し次のテストが同じDBを参照しようとした時に起こる。
この問題の一つの解決策は
Ajaxが終了していることをテストの最後に確認すること。
THOUGHTBOT, INC. の記事に一つの解決策を紹介している。
ソースコードはこちら
# 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を解決できた。