【问题标题】:Spork doesn't reload codeSpork 不会重新加载代码
【发布时间】:2012-05-04 22:39:37
【问题描述】:

我正在使用以下宝石和ruby-1.9.3-p194

  • 导轨 3.2.3

  • rspec-rails 2.9.0

  • spork 1.0.0rc2

  • guard-spork 0.6.1

Gemfile.lockGemfile 中提供了使用过的宝石的完整列表。

我正在使用这个配置文件:

如果我修改任何模型(或app/validators 等中的自定义验证器),重新加载代码将不起作用。

我的意思是当我运行规范时(在守卫控制台上按 Enter)Spork 包含“旧代码”并且我收到过时的错误消息。但是当我手动重新启动 Guard and Spork (CTRC-C CTRL-d guard) 时,一切正常。但是用了几次就累了。

问题:

有人可以查看我的配置文件并修复阻止更新代码的错误。

或者这可能是最新 Rails 版本的问题?


PS 这个问题在某些项目中反复出现(在某些项目中不存在)。但我还没弄清楚为什么会这样。

PS2 也许这个问题与ActiveAdmin有关?当我更改app/admin 中的文件时,代码会重新加载。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 rspec spork guard


    【解决方案1】:

    我遇到了同样的问题。测试已重新加载并成功运行以更改 model_spec.rb。当我对 model.rb 文件进行更改时,测试会重新运行,但代码似乎已被缓存 - 因此未应用更改。

    它需要几个答案的组合才能让事情发挥作用:

    # /config/environments/test.rb
    config.cache_classes = !(ENV['DRB'] == 'true')
    
    # spec_helper.rb
    Spork.each_run do
      .....
      ActiveSupport::Dependencies.clear
    end
    

    我还将 spork 更新到 (1.0.0rc3) 并用 spork-rails 替换了 spork gem,如上面@23inhouse 所述。但是,尽管升级 spork 可能有效果,但我没有看到 gemfile 中的任何一个 gem 之间有任何区别。

    希望这可以帮助其他人不要再花时间把头撞在墙上。

    【讨论】:

      【解决方案2】:

      解决方法:

      # config/environments/test.rb
      config.cache_classes = false
      

      但这是“双刃剑”。

      现在的规格运行时间要长约 2.0 倍。但它仍然比一次又一次地重新启动 Spork 更快。


      28.06.2013 更新

      使用Zeus。它完美地工作。基准在底部..

      如果您使用1.9.3,请考虑安装真正加快加载应用程序的特殊补丁。

      RVM patchsets

      rbenv instructions

      背景和基准:

      我有一个很大的1.9.3 应用程序,我想加快应用程序加载速度,Spork 无法正常工作,所以我开始寻找其他解决方案:

      我写了一个空规范来查看加载我的应用程序需要多长时间

      -/spec/empty_spec.rb

      require 'spec_helper'
      
      describe 'Empty' do
      
      end
      

      普通版 1.9.3

      time rspec spec/empty_spec.rb 64,65s user 2,16s system 98% cpu 1:07,55 total

      1.9.3 + rvm 补丁集

      time rspec spec/empty_spec.rb 17,34s user 2,58s system 99% cpu 20,047 total

      1.9.3 + rvm 补丁集 + 宙斯

      time zeus test spec/empty_spec.rb 0,57s user 0,02s system 58% cpu 1,010 total [w00t w00t!]

      【讨论】:

      • 是的,但是.. 它不是“纯”基准。我只是在使用该选项和不使用该选项时运行了几次规范。
      • 在我的项目中,不缓存类会导致 FactoryGirl 定义的间歇性错误在某些 Spork 运行后消失。缓存类解决了这个问题,但我又回到了原来的错误......
      • 宙斯是非常的车。尤其是在虚拟机上。
      【解决方案3】:

      Spork 得到了清理,并提取了一些功能。

      https://github.com/sporkrb/spork-rails

      将此添加到您的 Gemfile 中

      gem 'spork-rails'

      【讨论】:

      • 感谢您的回购 URL。我去看看。
      【解决方案4】:

      通过向 spork.each_run 方法添加更多内容解决了同样的问题。

      Rails 3.2.2

      另外,我建议一次运行一项测试。它速度更快,噪音更小,而且我们通常一次只进行一项测试。

      rspec spec -e 'shows answer text'
      

      我发现它比使用 Guard 更快更容易,因为我只是坐在那里等待 Guard 完成。此外,当我进行更改时,Guard 并不总是重新加载正确的文件并运行正确的测试。

      spec_helper.rb 文件:

      require 'spork'
      
      Spork.prefork do
        ENV['RAILS_ENV'] ||= 'test'
      
        require File.expand_path('../../config/environment', __FILE__)
        require 'rspec/rails'
        require 'rspec/autorun'
        require 'capybara/rspec'
        require 'capybara/rails'
      
        # Requires supporting ruby files with custom matchers and macros, etc,
        # in spec/support/ and its subdirectories.
      end
      
      Spork.each_run do
        Dir[Rails.root.join('spec/support/**/*.rb')].each {|f| require f}
      
        RSpec.configure do |config|
          # config.mock_with :mocha
          # config.mock_with :flexmock
          # config.mock_with :rr
          config.mock_with :rspec
      
          # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
          config.fixture_path = "#{::Rails.root}/spec/fixtures"
      
          # If you're not using ActiveRecord, or you'd prefer not to run each of your
          # examples within a transaction, remove the following line or assign false
          # instead of true.
          config.use_transactional_fixtures = true
      
          # If true, the base class of anonymous controllers will be inferred
          # automatically. This will be the default behavior in future versions of
          # rspec-rails.
          config.infer_base_class_for_anonymous_controllers = false
      
          config.include RequestHelpers, :type => :request
      
          config.before :suite do
            DatabaseCleaner.strategy = :truncation
            DatabaseCleaner.clean_with :truncation
          end
      
          config.before :each do
            DatabaseCleaner.start
          end
      
          config.after :each do
            DatabaseCleaner.clean
          end
      
          config.include(MailerHelpers)
          config.before(:each) { reset_email }
        end
        # This code will be run each time you run your specs.
      end
      

      【讨论】:

        【解决方案5】:

        在我的情况下,问题在于布料。它不允许 spork 重新加载模型。

        Spork.prefork do
          ENV['RAILS_ENV'] ||= 'test'
        
          # Routes and app/ classes reload
          require 'rails/application'
          Spork.trap_method(Rails::Application::RoutesReloader, :reload!)
          Spork.trap_method(Rails::Application, :eager_load!)
        
          # Draper preload of models
          require 'draper'
          Spork.trap_class_method(Draper::System, :load_app_local_decorators)
        
          # Load railties
          require File.expand_path('../../config/environment', __FILE__)
          Rails.application.railties.all { |r| r.eager_load! }
          ...
        

        只记得在加载环境之前为 Draper 插入陷阱方法。

        【讨论】:

          【解决方案6】:

          尽管 Spork 很棒,但它似乎在每次 Rails 升级时都会中断:(

          在 Rails 3.2.3 上,我在 spec/spec_helper.rb 中添加了这个 sn-p 以强制重新加载 app 目录中的所有 ruby​​ 文件。

          Spork.each_run do
            # This code will be run each time you run your specs.
            Dir[Rails.root + "app/**/*.rb"].each do |file|
              load file
            end
          end
          

          【讨论】:

          • 看起来是唯一可靠的方法(截至目前)。当然它会减慢速度,但总的来说它仍然比没有 spork 快
          • 我收回了。不要那样做。它不卸载类。这会导致 after_create 注册两次等等。
          【解决方案7】:

          或者,您可以为模型、控制器和其他代码添加保护。当这些文件中的任何一个发生变化时,它都会让守卫重新加载 spork。

          guard 'spork',
                :rspec_env => {'RAILS_ENV' => 'test'} do
            watch(%r{^app/models/(.+)\.rb$})
            watch(%r{^lib/(.+)\.rb$})
          end
          

          【讨论】:

          • 我测试了这种方法,但是......在几次重新加载后感到疲倦。
          • 厌倦了等待几秒钟? :)
          • 是的。 :) 重新加载 Spork 大约需要 20-30 秒(在我的 PC 上)。我通常运行单一规范(当我在重构等时更改模型时)。
          • 你必须有一个巨大的应用程序。或者古董 PC :) 我的 spork 需要 5-7 秒才能重新加载。
          • 第二个选项。 :D 这是 2009 年的笔记本电脑。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-22
          • 1970-01-01
          • 2012-04-04
          • 2020-10-26
          • 2012-01-09
          • 1970-01-01
          相关资源
          最近更新 更多