2

テストの失敗の原因を調査するのに非常に苦労しています。私は非常に経験豊富なプログラマーであり、一般的なデバッグ手法に精通していますが、Capybara と RSpec は初めてなので、私が知らない何らかの機能が役立つことを願っています。

要するに、次のようなテストがあります。

expect { click('.fake_button'); sleep 1 }.to change { clicks.count }.by(1)

偽のボタンがクリックされると、Rails アプリへの AJAX 呼び出しがトリガーされ、データベースにクリック レコードが追加されます。このテストが失敗する原因となっている可能性のある多くのことが考えられますが、ログから情報を取得することに成功したのは限られています。テストは開発で失敗することはなく、テストで散発的に失敗するだけです。テスト環境の違いの 1 つは、テストがクラウド内のサーバーに対してオフィス内のサーバーで実行されるため、ネットワークの遅延やその他の問題が発生する可能性があることです。

これを診断するのは非常に困難です。失敗したテストから得られる情報は非常に少なく、もちろん、失敗について読んだときにはすべてのデータベース情報が破棄されているからです。テストで変更されていないことはわかっており、成功したclicks.countと推測できclick('.fake_button')ますが、サーバー時間の同期の問題により、クリックが正しいボタンで発生したのか、AJAX 呼び出しが発生したのかさえわかりません。

私が望むのは、このテスト ケースを Web サーバーのログで追跡するのに役立つツール (たとえば、自動 URL パラメーターを使用するなど)、Capybara が行ったことに関する詳細なログ、および Web ページが変更されたときの Web ページの記録です。 Cookie 値を含め、エラーが発生しました。私はそれを手に入れることができますか?そのようなものはありますか?

4

3 に答える 3

3

カピバラは人間の行動をシミュレートします。テスト コードは必要なことを正確に実行します。これは、実際のユーザーが期待するものです。コードに文句を言うべきではないと思います。

ネットワークの遅延のために、待機時間を 1 から 2 に増やしても問題ないと思いますが、妥当な値を超えないようにしてください。そうしないと、アプリが実際のユーザーの期待どおりに機能しません。

Capybara コードをデバッグするには、要約したように 3 つの方法があります。

  1. 結果を見たい場所に「save_and_open_page」を追加します。次に、保存された html ページがテスト中に表示されます。(「launchy」gem を追加する必要があるかどうかは忘れました)

  2. このテストを一時的に JS として設定して、このテストがどのように進行するかを確認します。

    scenario "a fake test", js: true do
      # code here
    end
    

    これを行うと、実際のブラウザーがポップアップし、Capybara がコードをどのように再生するかを段階的に示します。

  3. $ tail log/test.log最近何が起こったかを示すために実行してください。

于 2013-03-27T07:22:42.323 に答える
1

@Billyが提案したことを構築しlog/test.logても、有用な情報が得られず、すでに使用していjs: trueたので、これを試しました:

begin
  expect { click('.fake_button'); sleep 1 }.to change { clicks.count }.by(1)
rescue Exception => e
  begin
    timestamp = Time::now.strftime('%Y%m%d%H%M%S%L')
    begin
      screenshot_name = "tmp/capybara/capybara-screenshot-#{timestamp}.png"
      $stderr.puts "Trying to save screenshot #{screenshot_name} due to test failure"
      page.save_screenshot(screenshot_name)
    rescue Exception => inner
      $stderr.puts "Ignoring exception #{inner} while trying to save screenshot of test page"
    end
    begin
      # Page saved by Capybara under tmp/capybara/ by default
      save_page "capybara-html-#{timestamp}.html"
    rescue Exception => inner
      $stderr.puts "Ignoring exception #{inner} while trying to save HTML of failed test page"
    end
  ensure
    raise e
  end
end

後で、テスト自体を次のようにして、Capybara の AJAX 同期機能を利用するように変更しました。

    starting_count = clicks.count
    click('.fake_button')
    page.should have_css('.submitted')     # Capybara is smart enough to wait for this to happen
    clicks.count.should == starting_count + 1

私が探している CSS は、AJAX コールバックによって JavaScript でページに追加されたものであるため、表示されるのは AJAX 呼び出しが完了したというシグナルであることに注意してください。

スクリーンショットは、ページ全体をレンダリングして画像に変換するのrescueに十分なメモリがないため、失敗率が高いため、ブロックは重要です。

編集

試したことはありませんが、有望な解決策はCapybara::Screenshotで、失敗するとスクリーンショットと HTML が自動的に保存されます。コードを読むだけで、スクリーンショットが失敗したときに問題が発生するように見え、スクリーンショットがトリガーされるまでにページがどのような状態になるかわかりませんが、試してみる価値があるようです.

于 2013-03-29T22:12:30.937 に答える
0

テストをデバッグする良い方法は、irb を使用してブラウザーで実際に何が起こっているかを確認することです。RSpec は通常、単純なケースでは適切な情報を提供できませんが、より複雑なケースについては、単純になるまでケースを分割するか、ライブ セッションのために irb にチャックして、本来の動作を確認します。

必ず :selenium をドライバーとして使用してください。Firefox が起動し、irb セッションで駆動できるようになるはずです。

于 2013-03-28T00:13:54.620 に答える