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 95 96 97 98 99 100 101 102 103 |
# File 'lib/elasticsearch/extensions/test/profiling.rb', line 54 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 |