Ruby on Rails集成测试期间的间歇性ActiveRecord :: RecordNotFound

aar*_*rkk 7 activerecord integration-testing ruby-on-rails ruby-on-rails-3

我有间歇性失败的集成测试,并且始终存在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
Run Code Online (Sandbox Code Playgroud)

更新以下是连续5次运行相同测试的结果.我运行测试,一直等到完成,然后立即用命令再次运行它们rails test:integration.注意:在整个测试中一致的E和F实际上是测试错误 - 我正在努力修复这些错误.例如,第二次测试运行是"正确的",但第一次显示虚假错误.

..E......E..........F.
.........E..........F.
..E......E..........F.
..E......E..........F.
..E....E.E..........F.
Run Code Online (Sandbox Code Playgroud)

错误确实发生在两个单独的表中 - 它们不是试图找到相同的记录.但它似乎只是具有此问题的测试的一部分......

更新以下是测试结果中的实际错误:

  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'
    ...
Run Code Online (Sandbox Code Playgroud)

请注意,当控制器尝试查找记录时,会出现错误.实际上是相关的@user = User.find(params[:id]).它也出现在其他模型中,而不仅仅是用户控制器而不仅仅是用户模型.

cfe*_*uke 5

我担心在数据截断期间可能会出现延迟以及Capybara驱动Web浏览器的速度,这有时可能会导致标识列值从意外值开始(即记录#1为7 - 当您期望1,因为身份生成器尚未重置).我没有证据证明这是事实,但这是我最好的猜测.

查看此URL上的第3项.这是一个非常直接的黑客,设置use_transactional_fixtures为true和monkeypatch ActiveRecord通过将代码粘贴到您的test_helper.rb.这有助于消除可能存在潜在问题的任何间歇性磁盘IO问题.

你可以尝试的另一件事是,该数据库的文件名设置为限制你的SQLite的测试数据库:memory:中的database.yml文件.这应该完成与上面相同的事情 - 消除可能导致这些间歇性问题的虚假磁盘IO.

  • 我将切入追逐并节省你很多时间:http://pryrepl.org/ - 安装它,设置你的`rails c`来使用它,然后在你的测试中你可以`binding.pry`和它将进入一个pry会话,你可以'ls`和`cd some_variable`来检查值; 你甚至可以运行ActiveRecord查询(`User.find_by_email(...)`)来查看当时数据库*实际上有什么* (2认同)