如何确保每个Minitest单元测试足够快?

时间:2018-11-04 18:29:24

标签: ruby minitest

我有大量的Minitest单元测试(方法),超过300种。它们都需要一些时间,从几毫秒到几秒钟。其中一些会偶尔挂断。我不知道是哪个,什么时候。

我想将Timeout应用于他们每个人,以确保如果花费了5秒以上的时间,任何人都会失败。可以实现吗?

例如:

class FooTest < Minitest::Test
  def test_calculates_something
    # Something potentially too slow
  end
end

1 个答案:

答案 0 :(得分:0)

您可以使用Minitest PLugin加载程序来加载插件。到目前为止,这是最干净的解决方案。但是,该插件系统的文档不是很好。

幸运的是,亚当·桑德森(Adam Sanderson)写了an article on the plugin system

最好的消息是,本文通过编写报告缓慢测试的示例插件来说明了插件系统。试用minitest-snail,这可能几乎是您想要的。

稍作修改,我们就可以使用Reporter将测试标记为失败(如果测试太慢),例如:(未测试)

文件minitest/snail_reporter.rb

module Minitest
  class SnailReporter < Reporter
    attr_reader :max_duration

    def self.options
      @default_options ||= {
        :max_duration => 2
      }
    end

    def self.enable!(options = {})
      @enabled = true
      self.options.merge!(options)
    end

    def self.enabled?
      @enabled ||= false
    end

    def initialize(io = STDOUT, options = self.class.options)
      super
      @max_duration = options.fetch(:max_duration)
    end

    def record result
      @passed = result.time < max_duration
      slow_tests << result if !@passed
    end

    def passed?
      @passed
    end

    def report
      return if slow_tests.empty?

      slow_tests.sort_by!{|r| -r.time}

      io.puts
      io.puts "#{slow_tests.length} slow tests."
      slow_tests.each_with_index do |result, i|
        io.puts "%3d) %s: %.2f s" % [i+1, result.location, result.time]
      end
    end
  end
end

文件minitest/snail_plugin.rb

require_relative './snail_reporter'

module Minitest
  def self.plugin_snail_options(opts, options)
    opts.on "--max-duration TIME", "Report tests that take longer than TIME seconds." do |max_duration|
      SnailReporter.enable! :max_duration => max_duration.to_f
    end
  end

  def self.plugin_snail_init(options)
    if SnailReporter.enabled?
      io = options[:io]
      Minitest.reporter.reporters << SnailReporter.new(io)
    end
  end

end