Module: Elasticsearch::Extensions::Test::Profiling
- Defined in:
- lib/elasticsearch/extensions/test/profiling.rb
Overview
Allows to define and execute profiling tests within [Shoulda](github.com/thoughtbot/shoulda) contexts.
Measures operations and reports statistics, including code profile.
Uses the “benchmark” standard library and the “ruby-prof” gem.
File: profiling_test.rb
require 'test/unit'
require 'shoulda/context'
require 'elasticsearch/extensions/test/profiling'
class ProfilingTest < Test::Unit::TestCase
extend Elasticsearch::Extensions::Test::Profiling
context "Mathematics" do
measure "divide numbers", count: 10_000 do
assert_nothing_raised { 1/2 }
end
end
end
$ QUIET=y ruby profiling_test.rb
...
ProfilingTest
-------------------------------------------------------------------------------
Context: Mathematics should divide numbers (10000x)
mean: 0.03ms | avg: 0.03ms | max: 0.14ms
-------------------------------------------------------------------------------
PASS (0:00:00.490) test: Mathematics should divide numbers (10000x).
...
Instance Method Summary collapse
-
#measure(name, options = {}, &block) ⇒ Object
Profiles the passed block of code.
Instance Method Details
#measure(name, options = {}, &block) ⇒ Object
TODO:
Try to make progress bar not to interfere with tests
Profiles the passed block of code.
measure "divide numbers", count: 10_000 do
assert_nothing_raised { 1/2 }
end
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/elasticsearch/extensions/test/profiling.rb', line 54 def measure(name, ={}, &block) ___ = '-'*ANSI::Terminal.terminal_width test_name = self.name.split('::').last context_name = self.context(nil) {}.first.parent.name count = Integer(ENV['COUNT'] || [:count] || 1_000) ticks = [] # progress = ANSI::Progressbar.new("#{name} (#{count}x)", count) should "#{name} (#{count}x)" do RubyProf.start count.times do ticks << Benchmark.realtime { self.instance_eval(&block) } # RubyProf.pause # progress.inc # RubyProf.resume end result = RubyProf.stop # progress.finish total = result.threads.reduce(0) { |total,info| total += info.total_time; total } mean = (ticks.sort[(ticks.size/2).round-1])*1000 avg = (ticks.inject {|sum,el| sum += el; sum}.to_f/ticks.size)*1000 max = ticks.max*1000 result.eliminate_methods!([/Integer#times|Benchmark.realtime|ANSI::Code#.*|ANSI::ProgressBar#.*/]) printer = RubyProf::FlatPrinter.new(result) # printer = RubyProf::GraphPrinter.new(result) puts "\n", ___, 'Context: ' + ANSI.bold(context_name) + ' should ' + ANSI.bold(name) + " (#{count}x)", "mean: #{sprintf('%.2f', mean)}ms | " + "avg: #{sprintf('%.2f', avg)}ms | " + "max: #{sprintf('%.2f', max)}ms", ___ printer.print(STDOUT, {}) unless ENV['QUIET'] || [:quiet] end end |