Simplecov测试覆盖率未报告Rake任务规范

时间:2017-02-05 00:16:05

标签: ruby-on-rails ruby rspec rake highline

我一直在争论为什么当我的规格通过撬测试正常工作时,没有报告这个Rake任务的Simplecov。有人能指出我正确的方向吗?

以下佣金任务......

namespace :myapp do
  namespace :data do
    namespace :load do
      desc 'Enqueue a range of dates by provider'
      task range: :environment do
        cli = HighLine.new
        msg('Select the dates for your data pull. Format: yyyy-mm-dd')
        created_before = cli.ask('Data created_before? ', Date)
        created_after = cli.ask('Data created_after? ', Date)
        if created_after >= created_before
          error_msg('The created_after date must be less than created_before!')
          exit
        else
          Resque.enqueue(AmazonMws::ImportOrdersJob, created_before: created_before, created_after: created_after)
        end
      end

      desc 'Enqueue from a specified date by provider'
      task from: :environment do
        cli = HighLine.new
        msg('Select the date for your data pull. Format: yyyy-mm-dd')
        created_from = cli.ask('Data created_from? ', Date)
        Resque.enqueue(AmazonMws::ImportOrdersJob, created_from: created_from)
      end
    end
  end
end

以下规格......

describe 'rake task myapp:data:load:from' do
  include_context 'rake'
  let(:task_path) { 'tasks/data.rake' }

  before do
    ResqueSpec.reset!
  end

  describe ':range' do
    let(:created_before) { '2017-01-02' }
    let(:created_after) { '2017-01-01' }
    let(:task_name) { 'myapp:data:load:range' }
    before do
      invoke_task.reenable
      allow(highline).to receive(:ask).with('Data created_before? ', Date).and_return(created_before)
    end

    it 'exits if created_after is not >= created_before' do
      allow(highline).to receive(:ask).with('Data created_after? ', Date).and_return(created_before)
      expect { invoke_task.invoke }.to raise_error(SystemExit)
    end

    # rubocop:disable RSpec/MultipleExpectations
    it 'exits with the right message' do
      allow(highline).to receive(:ask).with('Data created_after? ', Date).and_return(created_before)

      expect do
        expect { invoke_task.invoke }.to output('The created_after date must be less than created_before!').to_stdout
      end.to raise_error(SystemExit)
    end
    # rubocop:enable all

    it 'processes from a specified starting point' do
      allow(highline).to receive(:ask).with('Data created_after? ', Date).and_return(created_after)
      invoke_task.invoke
      expect(AmazonMws::ImportOrdersJob).to have_queue_size_of(1)
    end
  end

  describe ':from' do
    let(:created_from) { '2017-01-01' }
    let(:task_name) { 'myapp:data:load:from' }
    before do
      invoke_task.reenable
      allow(highline).to receive(:ask).and_return(created_from)
    end

    it 'processes from a specified starting point' do
      # expect(Resque).to receive(:enqueue).with(AmazonMws::ImportOrdersJob, created_from: created_from)
      invoke_task.invoke
      expect(AmazonMws::ImportOrdersJob).to have_queue_size_of(1)
    end
  end
end

rake任务的共享上下文......

shared_context 'rake' do
  let(:invoke_task) { rake[task_name] }
  let(:highline) { instance_double(HighLine) }
  let(:rake) { Rake::Application.new }

  before do
    Rake.application = rake
    load File.expand_path("#{Rails.root}/lib/#{task_path}", __FILE__)
    Rake::Task.define_task(:environment)
    allow(HighLine).to receive(:new).and_return(highline)
    # rubocop:disable all
    allow_any_instance_of(Object).to receive(:msg).and_return(true)
    allow_any_instance_of(Object).to receive(:error_msg).and_return(true)
    # rubocop:enable all
  end
end

更新

  • 调整了问题中的规范

enter image description here

1 个答案:

答案 0 :(得分:1)

SimpleCov使用Ruby标准库中的Coverage#result module来检查所涵盖的内容。当您使用内核Coverage#result重新加载文件时,load会重置文件(这是我的理论!)。

由于您在每个块执行之前加载data.rake,因此只会在结果中报告rspec文件中的最后一个规范。

您可以通过在使用before(:all)

运行所有示例之前加载任务一次来解决此问题

如下所示,快速更改共享上下文将为您提供所需的覆盖率报告。

RSpec.shared_context 'rake' do
  let(:invoke_task) { Rake.application[task_name] }
  let(:highline) { instance_double(HighLine) }

  before(:all) do
    Rake.application = Rake::Application.new
    Rails.application.load_tasks
  end    

  before do
    allow(HighLine).to receive(:new).and_return(highline)
    # rubocop:disable all
    allow_any_instance_of(Object).to receive(:msg).and_return(true)
    allow_any_instance_of(Object).to receive(:error_msg).and_return(true)
    # rubocop:enable all
  end
end