RSpec
Capybara

遅くならないfeature specの書き方ポイント

Rspec Slowest Test 改善

Rspecで遅くなっているテストの改善を実施したときのポイント
今回はRspec単体の実行時間改善を行い、CIの速度改善や並列実行は含みません。

前提

rspec (3.6.0)
capybara (2.15.3)
poltergeist (1.16.0)

遅いテスト例

$ bundle exec rspec --profile 10 spec/

Top 10 slowest examples (190.71 seconds, 37.6% of total time):
    127.35 seconds ./spec/features/furniture/search_spec.rb:35

:exclamation: :exclamation: :exclamation:

:bulb: ポイント

主にfeatureテストで遅くなるので、Capybaraを使ったテスト作成で気をつけるポイントを書いていきます。

ElasticSearchのindex作成のコードを意識する

  • ElasticSearchのindex作成をdocker上で行っています。
  • 改善以前にシナリオ毎にindex作成が2回走っていました。
  • 重くなる処理は必要のあるコードなのか意識しましょう。

Controllerのbefore_filterのテストをfeatureテストの対象にしない

  • featureテストでControllerのbefore_filterのテスト ( 主にログインの処理 )を書いている箇所を見かけますが、before_filterのテストはController側の債務としControllerSpec側で行う。

ログイン前提処理はcurrent_userのモックを使う

  • current_uerをモックする処理で、ログイン処理は飛ばしてしまいます。

sleepを使わない

  • Capybara.default_wait_timeが機能しているか確認し、sleepを使っている箇所を消していきます。

作成するデータ(FactoryGirl)は境界値を意識する。

  • テストケースを作成する際に必要な境界値以上のデータは作成しない。
  • 作成するデータ数そのままMysqlのInsertが走り遅くなります。 :bulb: 境界値分析

stub_constを使う

  • ページングのために大量のデータが作成されている場合があります。(PER_PAGE * ページ数分)

:exclamation: :expressionless:
ruby
200.times { create(:image_datum, :review) }

* :bulb: stub_constで定数のstubを作って、件数を減らします。

stub_const("PER_PAGE", 2)

withinを使う

  • withinでセレクタを指定する事により、ブロック内の検索対象をあらかじめ絞ることが出来ます。
within(:css, "li#employee") do
  fill_in 'Name', :with => 'Jimmy'
end
  • withinもCapybara.default_wait_timeを見ているのでページ遷移後にセレクタが見つからないときの対策として意識して使ってみてください。