我刚刚安装了SimpleCov gem来在我的Rails 3.2.6应用程序上生成代码覆盖率报告,它与RSpec配合使用非常好,而对Spork则无效。我可以通过运行rspec --no-drb spec/来获得所需的正确报告,但是我也想通过仅使用rspec spec/的Spork来获得它们。

鉴于有些人已经成功完成此任务,看来我的设置中有错误。我有read through the setup instructionsGitHub issue,它们声称为Spork用户提供了修复程序,但是仍然没有运气。我想知道是否有人可以提供其工作的 spec/spec_helper.rb 文件的完整示例,我可以将其用作引用,因为大量的Google搜索仅显示了摘要。根据其他站点的建议,我尝试将 config/environments/test.rb 中的config.cache_classes从默认的true更改为false更改为!(ENV['DRB'] == 'true'),但没有成功。

供引用,这是我的设置方式:

Gemfile

group :development, :test do
  # ...
  gem 'rspec-rails', '2.10.1'
end

group :test do
  # ...
  gem 'spork', '0.9.0'
  gem 'simplecov', '0.6.4', require: false
end

.spec
--colour
--drb

spec/spec_helper.rb (已根据GitHub issue进行了更改)
require 'simplecov'
SimpleCov.start 'rails'

require 'rubygems'
require 'spork'

Spork.prefork do
  unless ENV['DRB']
    require 'simplecov'
    SimpleCov.start 'rails'
  end

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

  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

  RSpec.configure do |config|
    config.mock_with :rspec
    config.fixture_path = "#{::Rails.root}/spec/fixtures"
    config.use_transactional_fixtures = true
    config.infer_base_class_for_anonymous_controllers = false
  end
end

Spork.each_run do
  if ENV['DRB']
    require 'simplecov'
    SimpleCov.start 'rails'
  end
end

我尝试注释掉/更改此文件的前两个SimpleCov语句和Spork块内的Simplecov语句,但似乎找不到有效的组合。

我想念什么?我还需要更改其他文件吗?

最佳答案

由于a comment on the Github issue将我发送到this blog entryits example spec/spec_helper.rb,我设法获得了一个有效的 spec/spec_helper.rb 配置,只需使用$ rspec spec/命令即可正确执行SimpleCov。起作用的所有原因都包含在(非常详细!)博客条目中。将SampleApp替换为您的应用程序的名称。

spec/spec_helper.rb

require 'rubygems'
require 'spork'

Spork.prefork do
  unless ENV['DRB']
    require 'simplecov'
    SimpleCov.start 'rails'
  end

  require 'rails/application'
  require Rails.root.join("config/application")

  ENV["RAILS_ENV"] ||= 'test'
  require 'rspec/rails'
  require 'rspec/autorun'

  RSpec.configure do |config|
    config.mock_with :rspec
    config.fixture_path = "#{::Rails.root}/spec/fixtures"
    config.use_transactional_fixtures = false

    config.before :each do
      if Capybara.current_driver == :rack_test
        DatabaseCleaner.strategy = :transaction
      else
        DatabaseCleaner.strategy = :truncation
      end
      DatabaseCleaner.start
    end

    config.after do
      DatabaseCleaner.clean
    end

    config.infer_base_class_for_anonymous_controllers = false
  end
end

Spork.each_run do
  if ENV['DRB']
    require 'simplecov'
    SimpleCov.start 'rails'
    SampleApp::Application.initialize!
    class SampleApp::Application
      def initialize!; end
    end
  end

  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
end

编辑

如果您使用Travis-CI,请不要按原样使用此代码,因为您可能会收到undefined method 'root' for Rails:Module (NoMethodError)错误。如果您知道如何解决此问题,请分享。

编辑2

我实际上是通过将所有内容放入Spork.each_run块来使Travis CI起作用的,这似乎大大降低了测试速度。必须有一个更好的方法来执行此操作,否则,由于不必一次运行$ rspec --no-drb spec/来获取SimpleCov报告,这似乎并不值得...

spec/spec_helper.rb
require 'rubygems'
require 'spork'

Spork.prefork do
  unless ENV['DRB']
    require 'simplecov'
    SimpleCov.start 'rails'
  end

  require 'rails/application'
  ENV["RAILS_ENV"] ||= 'test'
end

Spork.each_run do
  if ENV['DRB']
    require 'simplecov'
    SimpleCov.start 'rails'
    require Rails.root.join("config/application")
    SampleApp::Application.initialize!
    class SampleApp::Application
      def initialize!; end
    end
  end

  unless ENV['DRB']
    require File.expand_path("../../config/environment", __FILE__)
  end

  require 'rspec/rails'
  require 'rspec/autorun'

  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

  RSpec.configure do |config|
    config.mock_with :rspec

    config.fixture_path = "#{::Rails.root}/spec/fixtures"
    config.use_transactional_fixtures = false
    config.before :each do
      if Capybara.current_driver == :rack_test
        DatabaseCleaner.strategy = :transaction
      else
        DatabaseCleaner.strategy = :truncation
      end
      DatabaseCleaner.start
    end

    config.after do
      DatabaseCleaner.clean
    end
    config.infer_base_class_for_anonymous_controllers = false
  end
end

编辑3

在使用此配置几天后,它似乎并没有像我以前想象的那样放慢速度,因此除非发布了更优雅的答案,否则我将认为这是可接受的答案。

编辑4

使用此配置几个月后,我开始意识到它比我想象的要慢。部分原因在于,Spork似乎可以减慢测试套件的速度,并且最适合快速迭代的重点测试,而不是始终与之一起运行整个测试套件。以下SO问题和博客文章使我进入了下面的 spec_helper.rb 文件,该文件可以在有或没有Spork的情况下运行SimpleCov,运行速度比以前更快,并且可以与Capybara 2.0一起使用。
  • Rails project using spork - always have to use spork?
  • How to profile RSpec with perftools and bundler?
  • Spork.trap_method Jujitsu
  • When Spork puts a fork in your Cucumber and a spanner in yor specs
  • Crank your specs
  • Profiling Spork for faster start-up time
  • Sane RSpec config for clean, and slightly faster, specs

  • spec/spec_helper.rb
    require 'rubygems'
    require 'spork'
    require 'simplecov'
    #uncomment the following line to use spork with the debugger
    #require 'spork/ext/ruby-debug'
    
    Spork.prefork do
      ENV["RAILS_ENV"] ||= 'test'
      unless ENV['DRB']
        SimpleCov.start 'rails'
        require File.expand_path("../../config/environment", __FILE__)
      end
    
      require 'rspec/rails'
      require 'rspec/autorun'
      require 'capybara/rails'
      require 'capybara/rspec'
    
      # files to preload based on results of Kernel override code below
      # ie they took more than 100 ms to load
      require "sprockets"
      require "sprockets/eco_template"
      require "sprockets/base"
      require "active_record/connection_adapters/postgresql_adapter"
      require "tzinfo"
      require "tilt"
      require "journey"
      require "journey/router"
      require "haml/template"
    
      RSpec.configure do |config|
        config.mock_with :rspec
    
        # 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 = false
    
        # 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 FactoryGirl::Syntax::Methods
    
        config.before :suite do
          # PerfTools::CpuProfiler.start("/tmp/rspec_profile")
          DatabaseCleaner.strategy = :transaction
          DatabaseCleaner.clean_with(:truncation)
        end
    
        # Request specs cannot use a transaction because Capybara runs in a
        # separate thread with a different database connection.
        config.before type: :request do
          DatabaseCleaner.strategy = :truncation
        end
    
        # Reset so other non-request specs don't have to deal with slow truncation.
        config.after type: :request  do
          DatabaseCleaner.strategy = :transaction
        end
    
        RESERVED_IVARS = %w(@loaded_fixtures)
        last_gc_run = Time.now
    
        config.before(:each) do
          GC.disable
        end
    
        config.before do
          DatabaseCleaner.start
        end
    
        config.after do
          DatabaseCleaner.clean
        end
    
        # Release instance variables and trigger garbage collection
        # manually every second to make tests faster
        # http://blog.carbonfive.com/2011/02/02/crank-your-specs/
        config.after(:each) do
          (instance_variables - RESERVED_IVARS).each do |ivar|
            instance_variable_set(ivar, nil)
          end
          if Time.now - last_gc_run > 1.0
            GC.enable
            GC.start
            last_gc_run = Time.now
          end
        end
    
        config.after :suite do
          # PerfTools::CpuProfiler.stop
    
          # REPL to query ObjectSpace
          # http://blog.carbonfive.com/2011/02/02/crank-your-specs/
          # while true
          #   '> '.display
          #   begin
          #     puts eval($stdin.gets)
          #   rescue Exception => e
          #     puts e.message
          #   end
          # end
        end
      end
    
      # Find files to put into preload
      # http://www.opinionatedprogrammer.com/2011/02/profiling-spork-for-faster-start-up-time/
      # module Kernel
      #   def require_with_trace(*args)
      #     start = Time.now.to_f
      #     @indent ||= 0
      #     @indent += 2
      #     require_without_trace(*args)
      #     @indent -= 2
      #     Kernel::puts "#{' '*@indent}#{((Time.now.to_f - start)*1000).to_i} #{args[0]}"
      #   end
      #   alias_method_chain :require, :trace
      # end
    end
    
    Spork.each_run do
      # This code will be run each time you run your specs.
      if ENV['DRB']
        SimpleCov.start 'rails'
        SampleApp::Application.initialize!
        class SampleApp::Application
          def initialize!; end
        end
      end
    
      # Requires supporting ruby files with custom matchers and macros, etc,
      # in spec/support/ and its subdirectories.
      Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
      FactoryGirl.reload
      I18n.backend.reload!
    end
    

    关于ruby-on-rails-3 - 使用Spork运行RSpec测试后,SimpleCov报告未在Rails 3应用程序中生成,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11377460/

    10-11 23:47