7

断続的に失敗し、常にActiveRecord::RecordNotFoundエラーが発生する統合テストがあります。エラーはfind、フィクスチャからの ID を指定して呼び出しが行われるコントローラー内で発生します。ただし、複数のコントローラーで行われます。サイトをナビゲートしているときにこの動作が見られることはありませんが、テストは約 30 ~ 50% の確率で失敗すると思います。失敗後にテストを再度実行すると、問題が解決するようです。

フィクスチャを開発データベースに手動でロードすると、見つからないように見える ID が実際にテーブル内に存在します。

同じ問題を抱えている人について多くの情報を見つけることができませんでした...何かアイデアはありますか?

更新: test_helper.rb の内容は次のとおりです。

ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'capybara/rails'
class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
  #
  # Note: You'll currently still have to declare fixtures explicitly in integration tests
  # -- they do not yet inherit this setting
  fixtures :all
  # Add more helper methods to be used by all tests here...
end
# Transactional fixtures do not work with Selenium tests, because Capybara
# uses a separate server thread, which the transactions would be hidden
# from. We hence use DatabaseCleaner to truncate our test database.
DatabaseCleaner.strategy = :truncation
class ActionDispatch::IntegrationTest
  # Make the Capybara DSL available in all integration tests
  include Capybara::DSL
  # Make the Capybara Email DSL available in all integration tests
  include Capybara::Email::DSL
  # Stop ActiveRecord from wrapping tests in transactions
  self.use_transactional_fixtures = false
  # Switch to selenium as the default driver for JS support
  Capybara.default_driver = :selenium
  # Only click on visible links!
  Capybara.ignore_hidden_elements = true
  teardown do
    DatabaseCleaner.clean       # Truncate the database
    Capybara.reset_sessions!    # Forget the (simulated) browser state
    Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
  end
end

更新同じテストを 5 回続けて実行した結果は次のとおりです。テストを実行し、終了するまで待ってから、すぐにコマンドで再度実行しましたrails test:integration。注: テスト全体で一貫している E と F は、実際にはテスト エラーです。これらの修正に取り組んでいます。たとえば、2 回目のテスト ランスルーは「正しい」ものでしたが、最初のテストでは偽のエラーが表示されました。

..E......E..........F.
.........E..........F.
..E......E..........F.
..E......E..........F.
..E....E.E..........F.

エラーは 2 つの別々のテーブルで発生します。同じレコードを見つけようとしているわけではありません。しかし、この問題があるテストのサブセットにすぎないようです...

更新テスト結果で実際のエラーがどのように見えるかを次に示します。

  1) Error:
test_browsing_user_snops(BrowseStoriesTest):
ActiveRecord::RecordNotFound: Couldn't find User with id=980190962
    /home/myuser/.rvm/gems/ruby-1.9.3-p286/gems/activerecord-3.2.9/lib/active_record/relation/finder_methods.rb:341:in `find_one'
    /home/myuser/.rvm/gems/ruby-1.9.3-p286/gems/activerecord-3.2.9/lib/active_record/relation/finder_methods.rb:312:in `find_with_ids'
    /home/myuser/.rvm/gems/ruby-1.9.3-p286/gems/activerecord-3.2.9/lib/active_record/relation/finder_methods.rb:107:in `find'
    /home/myuser/.rvm/gems/ruby-1.9.3-p286/gems/activerecord-3.2.9/lib/active_record/querying.rb:5:in `find'
    /home/myuser/Projects/myproject/app/controllers/users_controller.rb:18:in `show'
    ...

コントローラーがレコードを検索しようとすると、エラーが表示されることに注意してください。関連する行は実際には@user = User.find(params[:id]). ユーザーコントローラーだけでなく、ユーザーモデルだけでなく、他のモデルでも発生します。

4

1 に答える 1

5

データの切り捨てと、Capybara が Web ブラウザーを駆動する速度の間に遅延が発生する可能性があることを心配しています。 ID ジェネレーターがまだリセットされていないため、1 が必要です)。これが事実であるという証拠はありませんが、私の最善の推測です。

この URL の項目 #3 を見てください。これは非常に簡単なハックで、use_transactional_fixturestrue に設定し、そのコードを に貼り付けて ActiveRecord をモンキーパッチしますtest_helper.rb。これは、潜在的な問題になる可能性のある断続的なディスク IO の問題を排除するのに役立ちます。

もう 1 つの試みとして、SQLite テスト データベースのファイル名をファイル内で に設定することで、そのデータベースを制限することができ:memory:ますdatabase.yml。これにより、上記と同じことが達成されます。これらの断続的な問題を引き起こしている可能性のある誤ったディスク IO が排除されます。

于 2012-11-29T02:03:32.930 に答える