ruby-on-rails - 具有多个应用程序的 SimpleCov - 或者简而言之,Simplecov 是如何工作的?

标签 ruby-on-rails ruby-on-rails-3 testing code-coverage

我正在尝试设置 SimpleCov 为 3 个应用程序生成报告,这些应用程序从本地 gem 共享大部分代码(模型、 Controller ),但每个应用程序使用的代码规范都在每个 ./spec 中,而不是在 gem 本身。

为了更清楚的例子。当我在使用本地 gem 的共享模型的 app_1 中运行 bundle exec rspec spec 时,我想获得(准确的)此 app_1 在 ./spec 中具有的所有规范的报告。

本地 gem 也有一些专用于 app_2 的模型,位于命名空间内,因此当我在 app_1 内运行测试套件时,我想跳过这些文件的报告。

我正在尝试使用类似于 app_1/spec/spec_helper 中的以下代码来实现此目的。

# This couple of lines are needed to generate report for the models, etc. inside the local gem.
SimpleCov.adapters.delete(:root_filter)
SimpleCov.filters.clear

SimpleCov.adapters.define 'my_filter' do
  root = SimpleCov.root.split("/")
  root.pop
  add_filter do |src|
    !(src.filename =~ /^#{root.join("/")}/)
  end

  add_filter "/app_2_namespace/"
end

if ENV["COVERAGE"] == "true"
  SimpleCov.start 'rails'
end

这有效,直到出现一些问题。

为什么我对 gem 内的模型获得 85% 的覆盖率,但规范在 app_2 内(我在 app_1 内运行规范)。

第一次出现问题是在我尝试改进该模型时,所以我单击了它的报告并查看了哪些行未被覆盖,然后我尝试修复它们,在 app_2/spec/namespace/上为它们编写测试my_model_spec.rb.

但这没有任何区别,我尝试了更积极的测试并删除了规范文件中的所有内容,但不知何故我仍然获得了 85% 的覆盖率,因此 my_model_spec.rb 与my_model.rb 的覆盖率结果。有点出乎意料。

但是由于这个文件在 app_2 上,我决定在 app_1 spec_helper 的 SimpleCov.start block 上添加一个过滤器,例如:

add_filter "/app_2_name_space/"

然后我移动到 app_2 文件夹并开始设置 SimpleCov 并查看我会在这里得到什么结果。结果他们更奇怪了。

对于同一模型,我获得了 100% 的覆盖率,我对清空 my_model_spec.rb 文件进行了相同的测试,但仍然获得了 100% 的覆盖率。所以这真的很糟糕,或者我不明白什么。

这是如何工作的?(with the Ruby 1.9 Coverage module 你说,好吧,当我在本地运行官方文档中的示例时,我得到了不同的结果,所以我认为那里有错误或过时的文档)

ruby-doc: {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]} 
locally:  {"foo.rb"=>[1, 1, 10, nil, nil, 1, 0, nil, 1, nil]}

我希望报告不会显示在应用代码某处评估的行的积极结果,无论在何处。

我认为预期的行为是模型的结果与其规范相关, Controller 的结果也是如此。

是这样吗?如果是这样,为什么我会得到这个奇怪的结果。

或者您认为我的应用程序的结构可能会与 SimpleCov 和 Coverage 混淆?

感谢您花时间阅读本文,如果您需要更详细的信息,请询问。

最佳答案

关于您对模型被 100% 覆盖的困惑,因为我不确定我是否理解正确:Coverage(以及 SimpleCov)无法知道您的代码是从规范执行还是“其他地方”执行”。假设我有一个方法“foo”和一个调用 foo 的方法“bar”。如果我在我的规范中调用 bar,当然 foo 也会显示为已覆盖。

关于您的一般问题:我认为报告覆盖率应该是可能的。仅仅因为源代码位于与您的项目根目录不同的位置,不应导致覆盖率报告丢失。

基本配置中的两件事:删除基本适配器(第 2 行)是不必要的,因为适配器基本上是美化的配置 block ,此时您已经执行了它(因为它在加载 Simplecov 时被调用)。重置过滤器应该就足够了。

此外,您定义的自定义适配器未被使用。请参阅 README 以了解如何正确设置适配器,但我认为当您现在开始覆盖运行时,只需在 SimpleCov 配置 block 中使用它就可以了:

SimpleCov.start 'rails' do
  your_custom_config
end

不过,您可能需要的是所有应用的合并覆盖率报告。为此,您必须首先在配置 block 内为每个规范套件定义一个 command_name,如下所示:command_name 'App1 Specs'

您还必须定义一个中央 coverage_path,它将存储您在应用程序套件中的覆盖率报告。假设您有 ~/projects/my_project/app[1-3],然后将其放入 my_project/coverage 可能有意义。这将导致您的不同测试套件结果合并到一个报告中,就像将 SimpleCov 与 Cucumber 和 RSpec 一起使用时一样。合并的默认超时时间约为 10 分钟,因此您可能需要在配置中使用 merge_timeout 3600 将其设置为更高的值(这些是秒)。有关这些配置选项的细节,请再次查看 README 和 SimpleCov::Configuration 文档。那里对这些内容进行了相当详细的概述。

因此,总而言之,您的每个应用都应该看起来像这样:

require 'SimpleCov'
SimpleCov.start 'rails' do
  reset_filters!
  command_name 'App1 Spec'
  coverage_path File.dirname(__FILE__) + '../../coverage' # Assuming this is in my_project/app1/spec/spec_helper.rb
  merge_timeout 3600
end

接下来您可能想要添加过滤器以按路径拒绝所有非项目 gem,并且您应该启动并运行。

关于ruby-on-rails - 具有多个应用程序的 SimpleCov - 或者简而言之,Simplecov 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9501607/

相关文章:

ruby-on-rails - ruby rails : Search form

ruby-on-rails - Rails SQLite Dev 和 Test 数据库是相同的。为什么?

mysql - 使用 mysql2 db 在本地主机上部署时出现语法错误、意外的 keywords_end 错误

javascript - 如何使用 vanilla javascript 触发窗口调整大小事件?

rest - 飞盘 : response data extraction and conditional execution

ruby-on-rails - 使用 ui-router 的 AngularJS 和 Rails 的多页 SPA

ruby-on-rails - 单例方法与类方法

html - 主页宽度 100% 宽度和其他(输入表单)窄宽度的 Rails 布局

ruby-on-rails - 如何删除主键?

windows - 如何在 Windows 10 触摸屏环境中测试 Web 应用程序? (browserstack 和 sauselabs 不起作用)