本文介绍了使用 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/.

鉴于有人在这方面取得了成功,我的设置似乎有误.我已经阅读安装说明以及 声称为 Spork 用户提供了修复,但仍然没有运气.我想知道是否有人可以提供他们工作 spec/spec_helper.rb 文件的完整示例,我可以将其用作参考,因为广泛的谷歌搜索只能找到片段.根据其他网站的建议,我尝试将 config/environments/test.rb 中的 config.cache_classestrue 的默认值更改为到 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:

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

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?

推荐答案

我设法获得了一个有效的 spec/spec_helper.rb 配置,只需使用 $ rspec spec/即可正确执行 SimpleCov 命令感谢 对 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,请不要按原样使用此代码,因为您会Rails:Module (NoMethodError) 错误可能会得到 undefined method 'root'.如果您知道如何解决此问题,请分享.

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.

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 应用程序中生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 13:29