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 次相同测试的结果。我运行测试,等到它们完成,然后立即使用 command 再次运行它们rails test:integration。注意:在整个测试中一致的 E 和 F 实际上是测试错误——我正在努力修复这些错误。例如,第二次测试运行是“正确的”,但第一次显示的是虚假错误。

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

这些错误确实发生在两个单独的表中——它们不是试图找到相同的记录。但它似乎只是有这个问题的测试的一个子集......

更新这是测试结果中实际错误的样子:

  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 浏览器的速度期间可能会有延迟,这有时可能会导致标识列值以意外值开始(即记录 #1 为 7 - 当您期望 1,因为该身份生成器尚未重置)。我没有证据表明情况确实如此,但这是我最好的猜测。

看看这个 URL 上的第 3 项。这是一个非常直接的 hack,use_transactional_fixtures通过将该代码粘贴到您的test_helper.rb. 这有助于消除可能是潜在问题的任何间歇性磁盘 IO 问题。

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

于 2012-11-29T02:03:32.930 回答