ruby-on-rails-3 - SimpleCov 报告使用 Spork 运行 RSpec 测试后未在 Rails 3 应用程序中生成

标签 ruby-on-rails-3 rspec code-coverage ruby-on-rails-3.2 spork

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

鉴于有人在这方面取得了成功,看来我的设置可能有错误。我有read through the setup instructions以及GitHub issue据称可以为 Spork 用户提供修复,但仍然没有成功。我想知道是否有人可以提供他们的工作 spec/spec_helper.rb 文件的完整示例供我引用,因为广泛的谷歌搜索只出现了片段。根据其他网站的建议,我尝试将 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 block 内的 Simplecov 语句,但似乎找不到有效的组合。

我错过了什么?还有其他文件需要更改吗?

最佳答案

我成功地获得了一个工作的spec/spec_helper.rb配置,只需使用$ rspec spec/命令即可正确执行SimpleCov,这要归功于a comment on the Github issue这将我发送到 this blog entry ,和its example spec/spec_helper.rb 。所有原因为什么都包含在(非常详细!)博客条目中。将 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 block 中来让 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 似乎可以减慢测试套件的速度,并且最适合快速迭代的集中测试,而不是总是用它运行整个测试套件。以下问题和博客文章让我找到了下面的 spec_helper.rb 文件,该文件可以在有或没有 Spork 的情况下运行 SimpleCov,运行速度比以前更快,并且可以与 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

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

相关文章:

unit-testing - JaCoCo 的分支覆盖,IntelliJ 的 Emma

MYSQL错误time.now

ruby-on-rails - Rails - 播种 HABTM 协会

ruby-on-rails - Michael Hartl 的 Rails 教程第 12 章——所有 54 个测试都失败了……?

testing - VSTS 中 .NET Core 项目的代码覆盖率和测试结果

java - 如何通过测试 Java 中指定复杂程度的方法来检查代码覆盖率

javascript - jQuery - 未获取元素 :enabled properly

ruby-on-rails - rswag gem 无法识别我在 rspec 中的参数

ruby - 如何创建沙盒 RSpec 环境?

ruby - Bundler 找不到 rake,但它似乎已安装