在执行gem binary

时间:2016-04-18 20:22:12

标签: ruby rspec

我正在尝试将SimpleCov coverage添加到我的带有二进制文件的gem。

我想测试它的命令行界面,所以我希望测试二进制执行本身,而不是它使用的库。

我没有得到SimpleCov的覆盖率报告(0 LOC)。

据我了解,问题很可能是因为在我的测试中(黄瓜特征或rspec规格),我正在用systempopen3执行gem的二进制文件,但我不知道我怎么能告诉SimpleCov“跟进”(或者如果我在正确的树上吠叫......)。

我尝试使用SimpleCov.command_nameSimpleCov.pid = $$SimpleCov.track_files以及我发现的几乎所有其他远程相关配置。

我不想使用Aruba,虽然我已经尝试检查他们的来源以寻找可能的答案。

相关代码段:

# spec_helper.rb
require 'simplecov'
SimpleCov.start

require 'rubygems'
require 'bundler'
Bundler.require :default, :development


# test_spec.rb
require 'spec_helper'

describe "my bin" do
  it "should be covered" do
    system 'bin/runme'
  end
end

我准备了一个minimal repo作为一个简单的试验场,如果这有帮助的话。

2 个答案:

答案 0 :(得分:1)

特别是找不到解决这个问题的方法并不容易。

不确定这会解决您的问题,但可能是一个开始?

没有修改过滤器的起始块我无法让SimpleCov观察bin目录(使用你提供的示例github repo)。

使用 command_name 为主进程覆盖报告一个名称,然后在fork used command_name中为forked进程报告一个名称(SimpleCov将它们合并为我们只要他们有不同的名字)。

然后使用 加载 加载bin文件,而不是使用 system

(我无法找到一种方法让 系统 产生 添加到覆盖率报告,可能是您通过脚本调用它,使用备用command_name重新启动SimpleCov

再次,不确定这是否正是您正在寻找的,但可能是一个开始。代码如下:

# spec_helper.rb
require 'simplecov'

SimpleCov.command_name "main_report"
SimpleCov.start do
    filters.clear # This will remove the :root_filter and :bundler_filter that come via simplecov's defaults
    add_filter do |src|
        !(src.filename =~ /^#{SimpleCov.root}/) unless src.filename =~ /bin/ #make sure the bin directory is allowed
    end
end

require 'rubygems'
require 'bundler'
Bundler.require :default, :development



# test_spec.rb
require 'spec_helper'

describe "my bin" do
    it "should be covered" do
        pid = Process.fork do
            SimpleCov.start do 
                command_name "bin_report_section"
            end
            load "bin/runme"
        end

    end
end

结果:

  

为bin_report_section生成的覆盖率报告,main_report为   /家庭/ korreyd / simplecov调试/覆盖。   1/11 LOC(100.0%)覆盖。

答案 1 :(得分:0)

您尝试过吗? https://blog.yossarian.net/2018/04/01/Code-coverage-with-Simplecov-across-multiple-processes

基本上,在您的spec_helper.rb

if ENV["COVERAGE"]
  require "simplecov"

  # Only necessary if your tests *might* take longer than the default merge
  # timeout, which is 10 minutes (600s).
  SimpleCov.merge_timeout(1200)

  # Store our original (pre-fork) pid, so that we only call `format!`
  # in our exit handler if we're in the original parent.
  pid = Process.pid
  SimpleCov.at_exit do
    SimpleCov.result.format! if Process.pid == pid
  end

  # Start SimpleCov as usual.
  SimpleCov.start
end

然后在bin / runme内添加:

  if ENV["COVERAGE"]
    # Give our new forked process a unique command name, to prevent problems
    # when merging coverage results.
    SimpleCov.command_name SecureRandom.uuid
    SimpleCov.start
  end

子进程的测试范围将合并到父进程中。

如果您使用SimpleCov的coverage_dir,请确保它在所有SimpleCov.start块中,以便将结果写入相同的位置。