0

我有一组针对 Rails 应用程序的 Test::Unit 测试。它是在 Ruby 1.8.6、Rails 2.3.4 下的 OS X 上开发的。

我也在使用thoughtbot-shoulda 2.10.2。

我使用的是标准 Rails 夹具,而不是工厂。

我已经将该项目签出到 CentOS Linux 5 工作站上,以供其他开发人员使用。他正在运行 Ruby 1.8.7。

(该应用程序正在生产中的 CentOS Linux 5 上运行,并且在那里运行良好。)

在我同事的 CentOS 开发机器上,所有的单元测试都通过了。

但是,大多数(但不是全部)功能测试都出错了。我已经隔离了一个测试(从项目中删除了所有其他测试)以缩小故障排除范围。

  context 'on DELETE to :destroy' do
    setup {
      delete(:destroy, { :id => addresses(:mary_publics_address).id }, stans_id)
    }
    should 'delete the address' do
      assert Address.find(:all, :conditions => {
        :id => addresses(:mary_publics_address).id
      } ).blank?
    end
    should 'delete the addresses phone numbers' do
      assert PhoneNumber.find(:all, :conditions => {
        :id => phone_numbers(:mary_publics_phone_number).id
      } ).blank?
    end
  end

我们得到的错误是......

[abc@abc contactdb]$ rake test:functionals --trace
(in /home/abc/projects/contactdb)

[ ... ]

/usr/local/ruby_187/bin/ruby -I"lib:test" "/home/abc/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/addresses_controller_test.rb" 
Loaded suite /home/abc/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.E
Finished in 0.426749 seconds.

  1) Error:
test: on DELETE to :destroy should delete the addresses phone numbers. (AddressesControllerTest):
ActiveRecord::RecordNotFound: Couldn't find Address with ID=1254595889
    /test/functional/addresses_controller_test.rb:107:in `__bind_1255114457_160068'
    /usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:369:in `call'
    /usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:369:in `run_current_setup_blocks'
    /usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:368:in `each'
    /usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:368:in `run_current_setup_blocks'
    /usr/local/ruby_187/lib/ruby/gems/1.8/gems/thoughtbot-shoulda-2.10.2/lib/shoulda/context.rb:350:in `test: on DELETE to :destroy should delete the addresses phone numbers. '

2 tests, 1 assertions, 0 failures, 1 errors
rake aborted!
Command failed with status (1): [/usr/local/ruby_187/bin/ruby -I"lib:test" ...]

我认为关键的谜团是为什么它找不到Address具有该 ID 的。

另一个因素是,当我注释掉这个块时,剩下的测试通过了。

    should 'delete the addresses phone numbers' do
      assert PhoneNumber.find(:all, :conditions => {
        :id => phone_numbers(:mary_publics_phone_number).id
      } ).blank?
    end

有人见过这个吗?

故障排除建议?

4

1 回答 1

2

关于 es 在 Ruby 中要意识到的一件事Hash是它们不保留顺序。在此之前我遇到了问题,根据内存中加载的代码更改哈希排序——即使在puts "foo"某处添加一个错误也会消失,因为我没有意识到Hash代码深处某处的排序有所不同。(注意:Hash在 1.9.1 中确实保留了排序,特别是因为这样的问题,如果我猜的话。)这与您所说的注释掉代码如何使其他代码通过的说法一致。由于大多数固定装置都是使用YAMLas Hashes 读取的,因此认为这可能是一个原因是合理的。找到Hash订购的地方(即在类似的地方each) 在您的情况下可能会或可能不会有意义。如果没有别的,这是要记住的事情。

您是否尝试过使用Fixtures.identify(:mary_publics_phone_number)而不是phone_numbers(:mary_publics_phone_number).id?(另请参阅:夹具文档。)要记住的另一件事:您可能没有唯一的夹具名称。我会检查重复项,以防万一。我认识很多人只是复制和粘贴固定装置,因为他们不知道YAML' 提供默认值的能力。在此过程中,他们可能会忘记更改灯具的名称。例子:

DEFAULTS: &DEFAULTS
  created_on: <%= 3.weeks.ago.to_s(:db) %>

first:
  name: Smurf
  <<: *DEFAULTS

我从 OS X 迁移到 Linux 时遇到的另一个问题是 Ruby 版本的细微差别。(即使两者都报告 1.8.6,请记住补丁级别很重要。)过去的情况是 Red Hat 版本的 Ruby 在垃圾收集器中存在内存泄漏,这需要我们有时重新启动长时间运行的进程。(在我们意识到发生了什么之前,它产生了一些难以发现的错误,因为它们不会在很长时间内发生时间。)由于 CentOS 与 Red Hat 相关(与 RHEL 基本相同),我可以想象其他版本差异会导致问题。我知道 OS X 从来没有我描述过的内存泄漏问题,这使得缩小错误范围变得更加困难。至于 1.8.6 和 1.8.7 之间的差异,您必须参考更改日志。请注意,从源代码构建的 Ruby 版本和打包版本的行为可能会有所不同——我认为内存泄漏问题是由打包 Ruby 的人引入的。

这些只是几个可能的原因。请报告您的发现!

于 2009-10-10T19:26:48.663 回答