LoginSignup
3
2

More than 5 years have passed since last update.

テスト内の無駄なhas_xxxマッチャをエラー出力する!

Last updated at Posted at 2015-07-02

2015/07/03 10:02 追記:
本記事内でCapybaraをモンキーパッチし、件名の処理を行っていましたが
コメントでのご指摘から、以下のように記述することでも可能であることを知りました。

test_spec.rb
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ではないため、間違っている可能性があればコメント欄にて教えて頂けると幸いです。。。

やること

やることはすごい簡単で対象の処理に対してモンキーパッチを行います。

spec_helper.rb
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なりが合っているか確認して、修正したりしましょー。

3
2
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2