【发布时间】:2014-09-12 15:56:44
【问题描述】:
我为此苦苦挣扎了很长一段时间:我正在尝试将 an app 从 Rails 3.2 升级到 Rails 4。在 Rails 3.2 all specs are passing 上时,它们在 Rails 4 中的某些条件下会失败。
某些规范在与其他规范一起运行时会单独通过而失败。
示例视频
https://www.wingolf.org/ak-internet-files/Spec_Behaviour.mp4(4 分钟)
此示例视频显示:
- 使用
:focus–––green 运行 3 个规范。 - 将它们与另一个规范一起运行——之前通过的两个规范现在失败了。
- 运行 3 个规范,但插入两个空行——一个规范失败。
- 使用保护时撤消没有帮助。
- 聚焦/不聚焦无济于事。
- 重新启动保护没有帮助。
- 运行所有规范,然后再次运行 3 个规范确实有助于使它们再次变绿。但是添加另一个任务又会导致两个规范失败。
正如我们所看到的,一些规格与其他规格一起运行时是红色的。即使输入空行也会有所作为。
更多观察
- 对于某些规范,多次运行时通过或失败随机发生。
- 该行为并非特定于一台开发机器,但可以在 travis 上重现。
- 使用database_cleaner 在规范之间完全删除数据库没有帮助。
- 在规范之间发送
Rails.cache.clear无济于事。 -
Wrapping each spec in an
ActiveRecord::Base.transaction没有帮助。 - Rails 4.0.0 和 Rails 4.1.1 中都会出现这种情况。
- 在没有spring 的情况下使用this minimal spec_helper.rb 或任何东西都无济于事。
- 使用guard 与直接使用
bundle exec rspec some_spec.rb:123没有区别。 - 此行为适用于模型规范,因此不必对功能规范的并行数据库连接执行任何操作。
- 我已经尝试将尽可能多的 gem 保留在与(绿色)Rails-3.2 分支中相同的版本,包括guard、rspec、factory_girl 等——但没有帮助。
更新:基于评论和答案的观察
-
Thanks to engineerDave,我已将
require 'pry'; binding.pry;插入到相关规格之一中。使用cdandshow-sourceofpry,缩小问题范围非常简单有趣:显然,thishas_many :throughrelation 与其他规范一起运行时不会返回对象,即使与(true)一起调用也是如此。has_many(:groups, -> { where('dag_links.descendant_type' => 'User').uniq }, through: :memberships, source: :ancestor, source_type: 'Group' )如果我直接调用
groups,我会得到一个空结果。但如果我通过memberships,则返回正确的组:@user.groups # => [] @user.groups(true) # => [] @user.memberships.collect { |m| m.group } # returns the correct groupsRails 是否以一种负责任的方式改变了 Rails 4 中的 has many through 行为?(请记住:该规范是独立工作的。)
感谢任何帮助、见解和经验。提前非常感谢!
代码
- Current master branch on Rails 3.2––全绿色。
- Rails-4 branch––奇怪的行为。
- The file/commit seen in the video––奇怪的行为。
- All specs passing on travis for Rails 3.2。
-
Diff of the
Gemfile.lock(或使用git diff master..sf/rails4-minimal-update Gemfile.lock |grep rspec)
如何复制
这是检查问题是否仍然存在的方法:
准备
git clone git@github.com:fiedl/wingolfsplattform.git
cd wingolfsplattform
git checkout sf/rails4-minimal-update
bundle install
# please create `config/database.yml` to your needs.
bundle exec rake db:create db:migrate db:test:prepare
运行规范
bundle exec rspec ./vendor/engines/your_platform/spec/models/user_group_membership_spec.rb
bundle exec rspec ./vendor/engines/your_platform/spec/models/user_group_membership_spec.rb:213
如果规范 :213 在第二次调用中为绿色但在第一次调用中与其他规范一起运行时为红色,则问题仍然存在。
【问题讨论】:
-
您没有在测试之间正确清理数据吗?
-
@sevenseacat,我试过 rspec 的 use_transactional_fixtures、database_cleaner 和 wrapping each spec in a transaction manually。还有其他更好的方法吗?
-
你确定你在测试环境中运行吗?
-
测试的顺序是固定的,还是随机运行的?如果您在升级 Rails 的同时升级了 rspec 版本,这种行为可能会发生变化。
-
我也怀疑这种奇怪的行为与您在规范中使用显式变量(例如@user)有关。我的猜测是变量从一个规范“泄漏”到另一个规范。我不使用显式变量,而是使用“let”语句,以确保值不会在规范之间泄漏。
标签: ruby-on-rails ruby-on-rails-4 rspec has-many-through