2015/07/03 10:02 追記:
本記事内でCapybaraをモンキーパッチし、件名の処理を行っていましたが
コメントでのご指摘から、以下のように記述することでも可能であることを知りました。
expect(page.has_xxx?("Foo bar")).to be_truthy
expect(page).to have_xxx "Foo bar"
一応、備忘録として本記事で書いていた内容はそのままにしておきますのでご注意下さい。
@jnchitoさん、@gongoさん ご指摘ありがとうございました!
================================================================
Capybaraを使っている方はAjaxが含まれるテスト等でhas_xxx(has_xpathやらhas_contentやら)のマッチャを使うことが多々あると思います。
ただ、このhas_xxxは実行時間がdefault_max_wait_time(またはdefault_wait_time)を超えた場合、何も出力などせずに次の処理へ移行します。
この時、最悪なパターンとしては
- has_xxxがdefault_max_wait_timeを超える
- 次の処理へ移行し、テストがパスされる
- 無駄にテスト時間が増えていく
という流れです。
これを防ぐために、default_max_wait_timeを超えた場合にはエラーを出力するようにしてみましょう!
※書いた人はRubyistではないため、間違っている可能性があればコメント欄にて教えて頂けると幸いです。。。
やること
やることはすごい簡単で対象の処理に対してモンキーパッチを行います。
module Capybara
module Node
module Matchers
def has_selector?(*args)
assert_selector(*args)
rescue Capybara::ExpectationNotMet
raise Capybara::CapybaraError
end
def has_no_selector?(*args)
assert_no_selector(*args)
rescue Capybara::ExpectationNotMet
raise Capybara::CapybaraError
end
def has_text?(*args)
assert_text(*args)
rescue Capybara::ExpectationNotMet
raise Capybara::CapybaraError
end
alias_method :has_content?, :has_text?
def has_no_text?(*args)
assert_no_text(*args)
rescue Capybara::ExpectationNotMet
raise Capybara::CapybaraError
end
alias_method :has_no_content?, :has_no_text?
end
end
end
各has_xxxでcallしてるメソッドを変えてる感じっす。
こうすることでdefault_max_wait_timeを食い潰す処理があれば以下のようにエラーが出るはずです。
Failures:
1) テスト
Failure/Error:
Capybara::CapybaraError:
Capybara::CapybaraError
# ./spec/spec_helper.rb:59:in `rescue in has_selector?'
# ./spec/spec_helper.rb:57:in `has_selector?'
# ./vendor/bundle/ruby/2.1.0/gems/capybara-2.4.4/lib/capybara/node/matchers.rb:201:in `has_css?'
# ./vendor/bundle/ruby/2.1.0/gems/capybara-2.4.4/lib/capybara/session.rb:676:in `block (2 levels) in <class:Session>'
# spec/steps/test_steps.rb:52:in `block (2 levels) in <top (required)>'
# ./vendor/bundle/ruby/2.1.0/gems/turnip-1.2.4/lib/turnip/execute.rb:25:in `step'
# ./spec/features/innova_blog/list_article.feature:22:in `run_step'
# ./vendor/bundle/ruby/2.1.0/gems/turnip-1.2.4/lib/turnip/rspec.rb:44:in `instance_eval'
# ./vendor/bundle/ruby/2.1.0/gems/turnip-1.2.4/lib/turnip/rspec.rb:44:in `run_step'
# ./spec/features/test.feature:19:in `block (6 levels) in run'
# ./spec/features/test.feature:18:in `each'
# ./spec/features/test.feature:18:in `block (5 levels) in run'
# ./spec/features/test.feature:22:in `'
あとは該当の処理が実際に見に行くElementなりが合っているか確認して、修正したりしましょー。