Capybara で CSSフレームワーク を用いた SPA をテストするのがつらい(レンダリング確定のためにウィンドウサイズ変更したり)

理由

  • 「たまに落ちる」が発生する
  • sleep や rspec-retry を使わないとうまくいかないことがある
    • sleep や rspec-retry は極力使うべきではない*1と思うので、超苦肉の策
  • マイナーなメソッドを探さないといけないことがある
    • 経験上、検索してもなかなかたどり着けない
    • Stack Overflow で見つかるケースが多い
  • data-test-id などの属性を埋め込めない
    • たとえば、table でテストしたい任意の行や列に任意の属性を埋め込むことができない(か、困難)
  • System Spec は回すために時間がかかる
    • トライアンドエラーを繰り返す際に大量の待ち時間が生まれる
      • ものすごい勢いで時間が溶けていく
    • ハマってしまうと 1日以上 費やしてしまうことは珍しくない
      • ハマっているときの徒労感がハンパない(後々に報われることが多いのだけれど)

どうするか

  • find は見つかるまで自動でループしてくれるので、find が使える方法を何とかして見出す
  • ある程度は諦める
    • E2E はそもそもコストが高い
    • sleep や rspec-retry 使うことで妥協する
  • 他の手段を用いる
    • 純粋な E2E ならば Puppeteer や Playwright や Cypress を使う

経験上の対応策の一つ(全く当てにならない)

ボタンをクリックしたら表示が変わる、のような場面で Flaky Test が発生しまくっている場合、ブラウザのウィンドウサイズを変更する位置業を挟んだら落ちなくなった(以下)。

# 「1920 x 1080」の部分は任意の数字を入れていい
Capybara.current_session.driver.browser.manage.window.resize_to(1920, 1080)

なお、ウィンドウサイズは現在のものと異なる値を入れないとたまに落ちる。理由は明確ではないが、もしかしたらサイズを変更することでレンダリングが明示的に走って落ちなくなるのかもしれない。

ただし、この方法で OK であるという確証は全く無く、ローカルで数十回ほど回して OK だっただけ*2

なお、find('#app#).click のようにしてフォーカスを外す操作を挟んでもやはりたまに落ちる。sleep を入れてもたまに落ちる。

以下の条件のもとでなら、この方法を用いてテストが通ったならそれで良しとしていいかとも思う。

  • ローカルで手動で動かして OK だった
    • 手動ウィンドウサイズ変更のパターンも含む
  • Flaky Test である

結論

Capybara で SPA のテストはつらい。

*1:Flaky Test の温床となってしまう

*2:たまたま通っただけかもしれない

Powered by はてなブログ