myronmarston-test_benchmarker 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ == 1.0.0 2009-03-27
2
+
3
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,14 @@
1
+ CHANGELOG
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib
6
+ lib/test_benchmarker
7
+ lib/test_benchmarker.rb
8
+ lib/test_benchmarker/core_ext.rb
9
+ lib/test_benchmarker/test_benchmarks.rb
10
+ lib/test_benchmarker/test_suite.rb
11
+ test
12
+ test/test_core_ext.rb
13
+ test/test_helper.rb
14
+ test/test_test_benchmarker.rb
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = test_benchmarker
2
+
3
+ * FIX (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ FIX (describe your package)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ * FIX (sudo gem install, anything else)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2009 Myron Marston, Kashless.org
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ task :default => :test
7
+
8
+ desc "Run All Tests"
9
+ Rake::TestTask.new :test do |test|
10
+ test.test_files = ["test/**/*.rb"]
11
+ test.verbose = true
12
+ end
13
+
14
+ desc %{Update ".manifest" with the latest list of project filenames. Respect\
15
+ .gitignore by excluding everything that git ignores. Update `files` and\
16
+ `test_files` arrays in "*.gemspec" file if it's present.}
17
+ task :manifest do
18
+ list = Dir['**/*'].sort
19
+ spec_file = Dir['*.gemspec'].first
20
+ list -= [spec_file] if spec_file
21
+
22
+ if File.exist?('.gitignore')
23
+ File.read('.gitignore').each_line do |glob|
24
+ glob = glob.chomp.sub(/^\//, '')
25
+ list -= Dir[glob]
26
+ list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob)
27
+ puts "excluding #{glob}"
28
+ end
29
+ end
30
+
31
+ if spec_file
32
+ spec = File.read spec_file
33
+ spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
34
+ assignment = $1
35
+ bunch = $2 ? list.grep(/^test\//) : list
36
+ '%s%%w(%s)' % [assignment, bunch.join(' ')]
37
+ end
38
+
39
+ File.open(spec_file, 'w') {|f| f << spec }
40
+ end
41
+ File.open('manifest.txt', 'w') {|f| f << list.join("\n") }
42
+ end
@@ -0,0 +1,7 @@
1
+ module TestBenchmarker
2
+ VERSION = '0.9.1'
3
+ end
4
+
5
+ require 'lib/test_benchmarker/test_benchmarks'
6
+ require 'lib/test_benchmarker/test_suite'
7
+ require 'lib/test_benchmarker/core_ext'
@@ -0,0 +1,25 @@
1
+ class TestBenchmarker::ClassNotFoundError < StandardError
2
+ attr_accessor :class_str
3
+ def initialize(class_str)
4
+ @class_str = class_str
5
+ end
6
+ end
7
+
8
+ class String
9
+ # similar to ActiveSupports constantize, but doesn't require the use of active support.
10
+ def to_class
11
+ ObjectSpace.each_object(Class) do |klass|
12
+ return klass if klass.to_s == self
13
+ end
14
+
15
+ raise TestBenchmarker::ClassNotFoundError.new(self), "A class matching '#{self}' could not be found"
16
+ end
17
+ end
18
+
19
+ class Class
20
+ def is_subclass_of?(klass)
21
+ return false if self == Object && klass != Object
22
+ return true if self == klass
23
+ return self.superclass.is_subclass_of?(klass)
24
+ end
25
+ end
@@ -0,0 +1,67 @@
1
+ require 'ostruct'
2
+
3
+ module TestBenchmarker
4
+ class TestBenchmark
5
+ attr_reader :test_class, :test_name, :benchmark
6
+
7
+ def initialize(test_class, test_name, benchmark)
8
+ @test_class, @test_name, @benchmark = test_class, test_name, benchmark
9
+ TestBenchmarks.add(self)
10
+ end
11
+ end
12
+
13
+ class TestBenchmarks
14
+ def self.clear
15
+ @@classes = {}
16
+ @@tests = []
17
+ end
18
+
19
+ self.clear
20
+
21
+ def self.add(benchmark)
22
+ test_class = benchmark.test_class
23
+
24
+ # ignore some bogus test classes that get passed here when run in the context of a rails app...
25
+ return if test_class =~ /(rake_test_loader|::TestCase|::IntegrationTest)/
26
+
27
+ begin
28
+ test_class = test_class.to_class
29
+ rescue TestBenchmarker::ClassNotFoundError
30
+ return
31
+ end
32
+ return unless test_class.is_subclass_of?(Test::Unit::TestCase)
33
+
34
+ @@classes[test_class] ||= OpenStruct.new
35
+ @@classes[test_class].benchmarks ||= []
36
+ @@classes[test_class].benchmarks << benchmark
37
+ @@tests << benchmark
38
+ end
39
+
40
+ def self.print_results
41
+ return if @@classes.nil? || @@classes.size == 0
42
+
43
+ benchmark_attr = :real
44
+
45
+ class_benchmarks = []
46
+ @@classes.each do |test_class, obj|
47
+ obj.test_count = obj.benchmarks.size
48
+ obj.sum = obj.benchmarks.inject(0) {|sum, bmark| sum + bmark.benchmark.send(benchmark_attr)}
49
+ obj.avg = obj.sum / obj.test_count
50
+ obj.test_class = test_class
51
+ class_benchmarks << obj unless obj.benchmarks.nil? || obj.benchmarks.size == 0
52
+ end
53
+
54
+ puts "\n\n#{'=' * 27} Class Benchmark Results #{'=' * 27}"
55
+ class_benchmarks.sort {|a, b| b.avg <=> a.avg}.each_with_index do |cb, i|
56
+ puts "#{i + 1}.#{' ' * (4 - (i + 1).to_s.length)} #{format("%.3f", cb.avg)} secs avg time, #{format("%.3f", cb.sum)} secs total time, #{cb.test_count} tests for: #{cb.test_class.to_s}"
57
+ end
58
+ puts "#{'=' * 79}\n\n"
59
+
60
+ puts "\n\n#{'=' * 28} Test Benchmark Results #{'=' * 28}"
61
+ @@tests.sort {|a, b| b.benchmark.send(benchmark_attr) <=> a.benchmark.send(benchmark_attr)}.each_with_index do |t, i|
62
+ puts "#{i + 1}.#{' ' * (4 - (i + 1).to_s.length)} #{format("%.3f", t.benchmark.real)} secs total time for: #{t.test_name}"
63
+ end
64
+ puts "#{'=' * 80}\n\n"
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,22 @@
1
+ require 'benchmark'
2
+
3
+ if ENV['BENCHMARK_TESTS']
4
+ class Test::Unit::TestSuite
5
+ @@run_count = 0
6
+
7
+ def run(result, &progress_block)
8
+ @@run_count += 1
9
+ begin
10
+ yield(STARTED, name)
11
+ @tests.each do |test|
12
+ TestBenchmarker::TestBenchmark.new(self.name, test.name, Benchmark.measure { test.run(result, &progress_block) })
13
+ end
14
+ yield(FINISHED, name)
15
+ ensure
16
+ @@run_count -= 1
17
+ # print the results as we're exiting the very last test run...
18
+ TestBenchmarker::TestBenchmarks.print_results if @@run_count == 0
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class Foo; end
4
+ class FooSubclass < Foo; end
5
+ class FooSubSubclass < FooSubclass; end
6
+ class Bar; end
7
+
8
+ class TestCoreExt < Test::Unit::TestCase
9
+ def test_string_to_class
10
+ assert_equal TestCoreExt, 'TestCoreExt'.to_class
11
+ assert_equal FooSubSubclass, 'FooSubSubclass'.to_class
12
+ end
13
+
14
+ def test_string_to_class_not_found
15
+ assert_raise TestBenchmarker::ClassNotFoundError do
16
+ 'This it not the name of a class!'.to_class
17
+ end
18
+ end
19
+
20
+ def test_class_is_subclass_of
21
+ assert FooSubclass.is_subclass_of?(Foo)
22
+ assert FooSubclass.is_subclass_of?(Object)
23
+
24
+ assert FooSubSubclass.is_subclass_of?(FooSubclass)
25
+ assert FooSubSubclass.is_subclass_of?(Foo)
26
+ assert FooSubSubclass.is_subclass_of?(Object)
27
+ end
28
+
29
+ def test_class_is_not_subclass_of
30
+ assert !Bar.is_subclass_of?(Foo)
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/test_benchmarker'
@@ -0,0 +1,117 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class Foo; end
4
+ class Class1 < Test::Unit::TestCase
5
+ def test_truth; end
6
+ end
7
+
8
+ class Class2 < Test::Unit::TestCase
9
+ def test_truth; end
10
+ end
11
+
12
+ class Class3 < Test::Unit::TestCase
13
+ def test_truth; end
14
+ end
15
+
16
+ class Class4; end
17
+
18
+ class TestTestBenchmarker < Test::Unit::TestCase
19
+ def setup
20
+ 1.upto(3) do |class_speed|
21
+ 1.upto(3) do |test_speed|
22
+ speed = class_speed * 0.01 + test_speed * 0.001
23
+ TestBenchmarker::TestBenchmark.new("Class#{class_speed}", "test_#{test_speed} (Class#{class_speed})", ::Benchmark.measure { sleep speed })
24
+ end
25
+ end
26
+
27
+ TestBenchmarker::TestBenchmark.new("Class4", "test_1 (Class4)", ::Benchmark.measure { sleep 0.01 })
28
+
29
+ @benchmarked_classes = TestBenchmarker::TestBenchmarks.send(:class_variable_get, '@@classes')
30
+ @benchmarked_tests = TestBenchmarker::TestBenchmarks.send(:class_variable_get, '@@tests').map{ |t| t.test_name }
31
+ @out, @err = util_capture { TestBenchmarker::TestBenchmarks.print_results }
32
+ end
33
+
34
+ def teardown
35
+ TestBenchmarker::TestBenchmarks.clear
36
+ end
37
+
38
+ def test_has_expected_benchmarked_classes
39
+ assert_equal 3, @benchmarked_classes.keys.size
40
+
41
+ assert @benchmarked_classes.keys.include?(Class1)
42
+ assert @benchmarked_classes.keys.include?(Class2)
43
+ assert @benchmarked_classes.keys.include?(Class3)
44
+ end
45
+
46
+ def test_does_not_have_classes_not_descended_from_test_unit_testcase
47
+ assert !@benchmarked_classes.keys.include?(Class4)
48
+ end
49
+
50
+ def test_has_expected_benchmarked_tests
51
+ assert_equal 9, @benchmarked_tests.size
52
+
53
+ assert @benchmarked_tests.include?('test_1 (Class1)')
54
+ assert @benchmarked_tests.include?('test_2 (Class1)')
55
+ assert @benchmarked_tests.include?('test_3 (Class1)')
56
+ assert @benchmarked_tests.include?('test_1 (Class2)')
57
+ assert @benchmarked_tests.include?('test_2 (Class2)')
58
+ assert @benchmarked_tests.include?('test_3 (Class2)')
59
+ assert @benchmarked_tests.include?('test_1 (Class3)')
60
+ assert @benchmarked_tests.include?('test_2 (Class3)')
61
+ assert @benchmarked_tests.include?('test_3 (Class3)')
62
+ end
63
+
64
+ def test_does_not_have_tests_not_descended_from_test_unit_testcase
65
+ assert !@benchmarked_tests.include?("test_1 (Class4)")
66
+ end
67
+
68
+ def test_class_benchmark_results
69
+ # should be in order from slowest to fastest
70
+ assert_match class_benchmark_regex('Class3', 1), @out
71
+ assert_match class_benchmark_regex('Class2', 2), @out
72
+ assert_match class_benchmark_regex('Class1', 3), @out
73
+ end
74
+
75
+ def test_test_benchmark_results
76
+ # should be in order from slowest to fastest
77
+ assert_match test_benchmark_regex('test_3 (Class3)', 1), @out
78
+ assert_match test_benchmark_regex('test_2 (Class3)', 2), @out
79
+ assert_match test_benchmark_regex('test_1 (Class3)', 3), @out
80
+ assert_match test_benchmark_regex('test_3 (Class2)', 4), @out
81
+ assert_match test_benchmark_regex('test_2 (Class2)', 5), @out
82
+ assert_match test_benchmark_regex('test_1 (Class2)', 6), @out
83
+ assert_match test_benchmark_regex('test_3 (Class1)', 7), @out
84
+ assert_match test_benchmark_regex('test_2 (Class1)', 8), @out
85
+ assert_match test_benchmark_regex('test_1 (Class1)', 9), @out
86
+ end
87
+
88
+ private
89
+
90
+ # borrowed from zentest assertions...
91
+ def util_capture
92
+ require 'stringio'
93
+ orig_stdout = $stdout.dup
94
+ orig_stderr = $stderr.dup
95
+ captured_stdout = StringIO.new
96
+ captured_stderr = StringIO.new
97
+ $stdout = captured_stdout
98
+ $stderr = captured_stderr
99
+ yield
100
+ captured_stdout.rewind
101
+ captured_stderr.rewind
102
+ return captured_stdout.string, captured_stderr.string
103
+ ensure
104
+ $stdout = orig_stdout
105
+ $stderr = orig_stderr
106
+ end
107
+
108
+ def class_benchmark_regex(class_name, slowness_ranking)
109
+ # http://rubular.com/regexes/6815
110
+ /^#{slowness_ranking}\.\s+[\d\.]+ secs avg time, [\d\.]+ secs total time, [\d]+ tests for: #{Regexp.escape(class_name)}$/
111
+ end
112
+
113
+ def test_benchmark_regex(test_name, slowness_ranking)
114
+ # http://rubular.com/regexes/6816
115
+ /^#{slowness_ranking}.\s+[\d\.]+ secs total time for: #{Regexp.escape(test_name)}$/
116
+ end
117
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: myronmarston-test_benchmarker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.1
5
+ platform: ruby
6
+ authors:
7
+ - Myron Marston
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-27 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: myron.marston@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - CHANGELOG
24
+ - README.rdoc
25
+ files:
26
+ - CHANGELOG
27
+ - Manifest.txt
28
+ - README.rdoc
29
+ - Rakefile
30
+ - lib
31
+ - lib/test_benchmarker
32
+ - lib/test_benchmarker.rb
33
+ - lib/test_benchmarker/core_ext.rb
34
+ - lib/test_benchmarker/test_benchmarks.rb
35
+ - lib/test_benchmarker/test_suite.rb
36
+ - test
37
+ - test/test_core_ext.rb
38
+ - test/test_helper.rb
39
+ - test/test_test_benchmarker.rb
40
+ has_rdoc: true
41
+ homepage: http://github.com/myronmarston/test_benchmarker
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --main
45
+ - README.rdoc
46
+ - --title
47
+ - TestBenchmarker Documentation
48
+ - --charset
49
+ - utf-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.2.0
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: A tool for benchmarking ruby Test::Unit tests
71
+ test_files:
72
+ - test/test_core_ext.rb
73
+ - test/test_helper.rb
74
+ - test/test_test_benchmarker.rb