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
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/elasticsearch/extensions/test/profiling.rb', line 71 def measure(name, ={}, &block) ___ = '-'*ANSI::Terminal.terminal_width test_name = name suite_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(suite_name, count) unless ENV['QUIET'] || [:quiet] should "#{test_name} (#{count}x)" do RubyProf.start begin count.times do ticks << Benchmark.realtime { self.instance_eval(&block) } if progress RubyProf.pause progress.inc RubyProf.resume end end ensure result = RubyProf.stop progress.finish if progress end total = result.threads.reduce(0) { |t,info| t += info.total_time; t } mean = (ticks.sort[(ticks.size/2).round-1])*1000 avg = (ticks.inject {|sum,el| sum += el; sum}.to_f/ticks.size)*1000 min = ticks.min*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", ___, "#{suite_name}: " + ANSI.bold(context_name) + ' should ' + ANSI.bold(name) + " (#{count}x)", "total: #{sprintf('%.2f', total)}s | " + "mean: #{sprintf('%.2f', mean)}ms | " + "avg: #{sprintf('%.2f', avg)}ms | " + "min: #{sprintf('%.2f', min)}ms | " + "max: #{sprintf('%.2f', max)}ms", ___ printer.print(STDOUT, {}) unless ENV['QUIET'] || [:quiet] end end |