本文介绍了使用Spork运行RSpec测试后,SimpleCov报告未在Rails 3应用程序中生成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚安装了 SimpleCov gem,以在Rails 3.2.6应用程序上生成代码覆盖率报告,并且它适用于RSpec,但不适用于Spork.我可以通过运行rspec --no-drb spec/来获得所需的正确报告,但是我也想通过仅使用rspec spec/来运行Spork来获得它们.

I just installed the SimpleCov gem to generate code coverage reports on my Rails 3.2.6 app, and it works great with RSpec, just not with Spork. I am able to get the desired correct report by running rspec --no-drb spec/, but I'd like to also get them with Spork running using just rspec spec/.

鉴于有些人在此方面取得了成功,看来我的设置中可能有错误.我已经通读了安装说明以及 GitHub问题声称有针对Spork用户的修复程序,但仍然没有运气.我想知道是否有人可以提供其工作的 spec/spec_helper.rb 文件的完整示例,我可以将其用作参考,因为大量的Google搜索仅显示了摘要.根据其他站点的建议,我尝试将 config/environments/test.rb 中的config.cache_classes从默认的true更改为false更改为!(ENV['DRB'] == 'true'),但没有好运

Given that there have been people who have had success with this, it seems likely I have errors in my setup. I have read through the setup instructions as well as the GitHub issue that purports to have a fix for Spork users, but still no luck. I'm wondering if there is anyone who can provide a full example of their working spec/spec_helper.rb file that I could use for reference, as extensive Googling has only turned up snippets. On the advice of other sites, I've tried changing the config.cache_classes in config/environments/test.rb from the default of true to false to !(ENV['DRB'] == 'true'), with no luck.

作为参考,这是我的设置方式:

For reference, this is how I'm setup:

宝石文件

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问题进行了更改)

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语句,但似乎找不到有效的组合.

I've tried commenting out/changing the top two SimpleCov statements of this file and the Simplecov statements inside the Spork blocks, but can't seem to find a combination that works.

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

What am I missing? Are there any other files I need to change?

推荐答案

由于对Github问题的评论,这使我成为此博客条目,以及其示例 spec/spec_helper.rb . 为什么起作用的所有原因都包含在(非常详细!)博客条目中.将SampleApp替换为您的应用程序名称.

I managed to get a working spec/spec_helper.rb configuration that executes SimpleCov correctly simply using the $ rspec spec/ command thanks to a comment on the Github issue that sent me to this blog entry, and its example spec/spec_helper.rb. All reasons why this works are contained in the (very detailed!) blog entry. Replace SampleApp with the name of your application.

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)错误.如果您知道如何解决此问题,请分享.

Edit

If you use Travis-CI, don't use this code as-is because you'll likely get a undefined method 'root' for Rails:Module (NoMethodError) error. If you know how to fix this, please share.

我实际上通过将所有内容放在Spork.each_run块中来使Travis CI正常工作,这似乎大大降低了测试速度.必须有一个更好的方法来执行此操作,否则似乎不必这样做,因为不必运行$ rspec --no-drb spec/一次即可获取SimpleCov报告...

I got Travis CI to work by essentially putting everything in the Spork.each_run block, which seems to have slowed down the tests significantly. There must be a better way to do this, or it just doesn't seem worth it for the sake of not having to run $ rspec --no-drb spec/ once to get the SimpleCov report...

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

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

Edit 3

After using this config for a few days, it doesn't seem to have slowed down things as much as I previously thought, so I'll consider this the accepted answer unless a more elegant one is posted.

使用此配置几个月后,我开始意识到它 比我想象的要慢.部分原因在于,Spork似乎可以减慢测试套件的速度,并且最适合快速迭代的重点测试,而不是始终与之一起运行整个测试套件.以下SO问题和博客文章使我进入下面的 spec_helper.rb 文件,该文件可以在带有或不带有Spork的情况下运行SimpleCov,运行速度比以前更快,并且可以与Capybara 2.0一起使用.

After using this config for a few months, I've come to realize that it is slower than I thought. Part of that is the realisation that it seems that Spork can slow down test suites, and is best for fast iterative focused testing vs always running entire test suites with it. The following SO questions and blog posts got me to the spec_helper.rb file below, which can run SimpleCov with or without Spork, runs faster than before, and works with 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

这篇关于使用Spork运行RSpec测试后,SimpleCov报告未在Rails 3应用程序中生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 11:59