【问题标题】:Spork/Autotest not picking up changes automaticallySpork/Autotest 不会自动获取更改
【发布时间】:2013-12-24 23:42:53
【问题描述】:

我正在按照http://ruby.railstutorial.org/ 的教程开发我的第一个 Rails 应用程序。我已经完全按照教程中的说明设置了我的开发环境(我正在使用带有 Lion 的 Macbook Pro),并且它可以正常工作,除了一个小问题。我首先编写失败的测试,然后对代码进行更改以使其通过,我可以在浏览器中检查页面是否正常工作,但由于某种原因,测试结果仍然是“红色”。我有一个运行 3 个选项卡的终端,第一个选项卡在其中运行 spork(bundle exec spork),第二个选项卡在其中运行 rails 服务器(rails s),第三个选项卡在其中进行所有命令行更改并运行测试(autotest || 捆绑执行 rspec 规范/)。我必须重新启动 spork、rails 服务器,然后再次测试以查看它们是否变为“绿色”。

这是预期的行为吗?因为根据教程,大多数时候我应该能够看到它们变绿而无需重新启动服务器/spork。

编辑

这就是我的 spec_helper.rb 文件的样子

require 'rubygems'
require 'spork'

Spork.prefork do
  # Loading more in this block will cause your tests to run faster. However,
  # if you change any configuration or code from libraries loaded here, you'll
  # need to restart spork for it take effect.

  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'


  # Requires supporting files with custom matchers and macros, etc,
  # in ./support/ and its subdirectories.
  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

  RSpec.configure do |config|
    # == Mock Framework
    #
    # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
    #
    # config.mock_with :mocha
    # config.mock_with :flexmock
    # config.mock_with :rr
    config.mock_with :rspec

    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, comment the following line or assign false
    # instead of true.
    config.use_transactional_fixtures = true
  end

end

Spork.each_run do
  # This code will be run each time you run your specs.
end

感谢您的建议!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 autotest spork


    【解决方案1】:

    我在尝试使用 spork 和 watchr 设置环境时遇到了同样的问题,并在这里找到了解决方案(至少在我的情况下):http://www.rubyinside.com/how-to-rails-3-and-rspec-2-4336.html

    编辑config/environments/test.rb

    改变

    config.cache_classes = true
    

    config.cache_classes = false
    

    这应该会让 spork 无需重新启动即可获取对控制器和模型的更改。

    编辑:

    我已经遇到了将 cache_classes 设置为 false 的问题(它导致了机械师和黄瓜的问题 - rspec 和机械师都很好)。

    无论如何,似乎有一个更好的解决方案(取自此处:http://ablogaboutcode.com/2011/05/18/spork-rspec-sham-and-caching-classes/ 和此处:http://mikbe.tk/2011/02/10/blazingly-fast-tests/),即将以下代码添加到您的 Spork.each_run 块

    Spork.each_run do
      ActiveSupport::Dependencies.clear
      ActiveRecord::Base.instantiate_observers
    
      load "#{Rails.root}/config/routes.rb"
      Dir["#{Rails.root}/app/**/*.rb"].each { |f| load f }  
    end if Spork.using_spork?
    

    【讨论】:

    • +1 用于实际尝试解决 OP 的问题。明天我会尝试测试一下。干杯!
    • 谢谢!我不知道为什么在为项目初始化 RSpec 时不包含这个。
    【解决方案2】:

    如果您在不进行更改的情况下运行测试,它会起作用吗?我的意思是它会“拾取”您的更改吗?

    如果是这种情况,请打开 spec_helper.rb 并更改 each_run 块,以便它每次加载您需要的测试需求,而不仅仅是加载一次。

    【讨论】:

    • 它会选择新的测试,它不会选择对代码进行的更改以使测试通过。我修改了我的问题,向您展示了 spec_helper.rb 文件的结构。
    • 您能告诉我我应该在 each_run 中添加什么以确保在每次测试运行之前获取所有更改吗?我的更改包括“对 routes.rb 的更改、对控制器方法的更改、对部分和视图的更改)。
    【解决方案3】:

    如果您使用 spork rc 1.0,则需要改用“spork-rails”。

    修复了控制器不为我重新加载的问题。感谢这篇文章。

    http://blog.firsthand.ca/2012/02/heads-up-use-spork-rails-if-you-want-to.html

    【讨论】:

      【解决方案4】:

      我正在学习相同的教程并遇到了相同的问题。以下是最终为我工作的内容:

      1. 更新“spec/spec_helper.rb”文件以将“Spork.prefork”部分更改为:

        Spork.prefork do
        
          # Loading more in this block will cause your tests to run faster. However,
          # if you change any configuration or code from libraries loaded here, you'll 
          # need to restart spork for it take effect.
        
          ENV["RAILS_ENV"] ||= 'test'
          require File.expand_path("../../config/environment", __FILE__)
          require 'rspec/rails'
        
          # Requires supporting files with custom matchers and macros, etc, 
          # in ./support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
        
          RSpec.configure do |config|
        
          # == Mock Framework
          #
          # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: #
          # config.mock_with :mocha
          # config.mock_with :flexmock 
          # config.mock_with :rr config.mock_with :rspec
              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, comment the following line or assign false 
          # instead of true.
        
          config.use_transactional_fixtures = true
          end  
        
        end
        
      2. 更新 'config/environments/test.rb' 文件进行更改:

        config.cache_classes = true
        

        收件人:

        config.cache_classes = false
        

      这是书中没有提到的第二点。我通过交叉引用其他 StackOverflow 问题找到了答案。就我而言,在关闭“config.cache_classes”之前,我对控制器所做的任何更改都会使测试套件运行,但它不会考虑编辑。根据上次测试运行,这将导致误报和误报。禁用设置后,测试会提取我的编辑并提供有效的通过/失败指示器,据我所知。


      请注意,如果一个视图 (.erb) 文件通过了一次测试,那么如果您对其进行更改,它似乎不会再次被拾取。但是,如果视图失败,spork 似乎会一直观察它的变化,直到它通过。

      【讨论】:

        【解决方案5】:

        添加到 Sam Peacey 的答案中,在较新版本的 Rails 中, instanceate_observers 已被弃用,删除该行仍会产生所需的结果:

        Spork.each_run do
          ActiveSupport::Dependencies.clear
        
          load "#{Rails.root}/config/routes.rb"
          Dir["#{Rails.root}/app/**/*.rb"].each { |f| load f }  
        end if Spork.using_spork?
        

        【讨论】:

          【解决方案6】:

          在 env.rb(设置 spork 的文件)中有两个块 preforkeach_run。在这里您可以解释他们的工作:

          Spork.prefork do
                # Loading more in this block will cause your tests to run faster. However, 
                # if you change any configuration or code from libraries loaded here, you'll
                # need to restart spork for it take effect.
          end
          

          Spork.each_run do
              # This code will be run each time you run your specs.
          end
          

          我认为它是自我描述的;)

          【讨论】:

          • 您能告诉我应该在 each_run 中添加什么以确保在每次测试运行之前获取所有更改吗?
          • 可能一切都来自 prefork ;) 但你不应该这样做。 Spork 用于使您的测试加载更快。所以你应该把尽可能多的东西放在 prefork 中。我知道当您更改代码中的某些内容时重新加载 Spork 会带来一些不便,但是...通常,您将在完成一些工作并手动测试后编写测试。因此不需要更改代码。在这种情况下,您会很高兴在每次更改后(在此测试中)测试开始得更快。
          • 好的,所以基本上我应该做的是每次我进行一组更改时重新启动 spork,而不是期望它自动拾取它?
          • 是的 - 如果您更改模型/控制器中的某些内容。如果您更改视图中的某些内容,那么它应该可以在不重新启动的情况下工作。
          • 您的“解决方案”假定(甚至促进)非 TDD 工作流程,并且不能解决 OP 所述的问题。因此:投反对票。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-14
          • 1970-01-01
          • 2016-11-02
          • 2019-02-21
          相关资源
          最近更新 更多