Reputation: 105213
I have a large amount of Minitest unit tests (methods), over 300. They all take some time, from a few milliseconds to a few seconds. Some of them hang up, sporadically. I can't understand which one and when.
I want to apply Timeout
to each of them, to make sure anyone fails if it takes longer than, say, 5 seconds. Is it achievable?
For example:
class FooTest < Minitest::Test
def test_calculates_something
# Something potentially too slow
end
end
Upvotes: 0
Views: 476
Reputation: 27603
You can use the Minitest PLugin loader to load a plugin. This is, by far, the cleanest solution. The plugin system is not very well documented, though.
Luckily, Adam Sanderson wrote an article on the plugin system.
The best news is that this article explains the plugin system by writing a sample plugin that reports slow tests. Try out minitest-snail, it is probably almost what you want.
With a little modification we can use the Reporter
to mark a test as failed if it is too slow, like so (untested):
File 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
File 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
Upvotes: 2