monkeytest 0.2.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/monkeytest +3 -23
- data/lib/monkeytest.rb +16 -159
- data/lib/monkeytest/cli.rb +194 -0
- data/lib/monkeytest/test.rb +16 -0
- data/lib/monkeytest/test_loader.rb +5 -0
- data/lib/monkeytest/testclass.rb +49 -0
- data/lib/monkeytest/testsuite.rb +58 -0
- data/lib/monkeytest/ui.rb +118 -0
- data/lib/monkeytest/ui/console.rb +69 -0
- data/lib/monkeytest/version.rb +10 -0
- metadata +12 -5
- data/lib/tasks/monkey.rake +0 -77
data/bin/monkeytest
CHANGED
@@ -1,24 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'monkeytest/cli'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
unless File.exist?("#{cwd}#{File::SEPARATOR}lib#{File::SEPARATOR}tasks")
|
7
|
-
puts "\tcreate lib/tasks"
|
8
|
-
Dir.mkdir("#{cwd}#{File::SEPARATOR}lib#{File::SEPARATOR}tasks")
|
9
|
-
else
|
10
|
-
puts "\texists lib/tasks"
|
11
|
-
end
|
12
|
-
|
13
|
-
if File.exist?("#{cwd}#{File::SEPARATOR}lib#{File::SEPARATOR}tasks#{File::SEPARATOR}monkey.rake")
|
14
|
-
puts "\treplace lib/tasks/monkey.rake"
|
15
|
-
else
|
16
|
-
puts "\tcreate lib/tasks/monkey.rake"
|
17
|
-
end
|
18
|
-
|
19
|
-
begin
|
20
|
-
cp("#{File.dirname(__FILE__)}#{File::SEPARATOR}..#{File::SEPARATOR}lib#{File::SEPARATOR}tasks#{File::SEPARATOR}monkey.rake","#{cwd}#{File::SEPARATOR}lib#{File::SEPARATOR}tasks#{File::SEPARATOR}monkey.rake")
|
21
|
-
rescue Exception => e
|
22
|
-
puts "There was a problem copying the file!"
|
23
|
-
puts e
|
24
|
-
end
|
4
|
+
MonkeyTest::CLI.fling!
|
data/lib/monkeytest.rb
CHANGED
@@ -1,164 +1,21 @@
|
|
1
|
+
require 'test/unit'
|
1
2
|
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def self.run_tests(mode, html=false)
|
10
|
-
|
11
|
-
if File.new("./lib/tasks/monkey.rake").read.match(/created with monkeytest 0.2/).nil?
|
12
|
-
puts "It looks like you've updated your gem.\nPlease run monkeytest again on your project."
|
13
|
-
exit 1
|
14
|
-
end
|
15
|
-
|
16
|
-
quiet = ((mode.to_s == "quiet") or (mode.to_s == "q"))
|
17
|
-
silent = ((mode.to_s == "silent") or (mode.to_s == "s"))
|
18
|
-
directories = DIRECTORIES.collect {|dir| File.expand_path(dir) }
|
19
|
-
failures = Array.new
|
20
|
-
totalTests = totalAsserts = totalErrors = totalFailures = 0
|
21
|
-
|
22
|
-
if html
|
23
|
-
puts "<div id='monkeytest'>"
|
24
|
-
end
|
25
|
-
|
26
|
-
directories.each do |dir|
|
27
|
-
if html
|
28
|
-
puts "<div style='margin-bottom: 1em;'><div style='font-weight: bold;'>#{dir.match(/\/([^\/]+)\/?$/)[1].upcase} TESTS:</div><table style='width: 550px;'>"
|
29
|
-
else
|
30
|
-
puts "\n#{dir.match(/\/([^\/]+)\/?$/)[1].upcase} TESTS:".bold
|
31
|
-
end
|
32
|
-
Dir.foreach(dir) do |file|
|
33
|
-
if file.match(PATTERN)
|
34
|
-
if html
|
35
|
-
print "<tr><td style='width: 50%; padding-left: 8px;'>#{file}</td>"
|
36
|
-
else
|
37
|
-
print " #{file.ljust(35)}"
|
38
|
-
end
|
39
|
-
|
40
|
-
fullResult = `ruby -C \"#{dir}\" \"#{dir}/#{file}\"`
|
41
|
-
|
42
|
-
result = fullResult.match(/([\d]+) tests, ([\d]+) assertions, ([\d]+) failures, ([\d]+) errors/) or break
|
43
|
-
numTests = result[1].to_i
|
44
|
-
numAsserts = result[2].to_i
|
45
|
-
numFailures = result[3].to_i
|
46
|
-
numErrors = result[4].to_i
|
47
|
-
|
48
|
-
totalTests += numTests
|
49
|
-
totalAsserts += numAsserts
|
50
|
-
totalErrors += numErrors
|
51
|
-
totalFailures += numFailures
|
52
|
-
|
53
|
-
if html
|
54
|
-
print "<td style='width: 20%; text-align:right;'>#{numTests.to_s} Tests</td>"
|
55
|
-
print "<td style='width: 20%; text-align:right;'>#{numAsserts.to_s} Assertions</td>"
|
56
|
-
else
|
57
|
-
print "#{numTests.to_s.rjust(4)} Tests "
|
58
|
-
print "#{numAsserts.to_s.rjust(4)} Assertions "
|
59
|
-
end
|
60
|
-
|
61
|
-
if numErrors > 0 then
|
62
|
-
if html
|
63
|
-
puts "<td style='color: red; width: 10%; text-align:right;'>ERROR</td></tr>"
|
64
|
-
else
|
65
|
-
puts "ERROR".red
|
66
|
-
end
|
67
|
-
failures.push fullResult
|
68
|
-
elsif numFailures > 0 then
|
69
|
-
if html
|
70
|
-
puts "<td style='color: yellow; width: 10%; text-align:right;'>FAIL</td></tr>"
|
71
|
-
else
|
72
|
-
puts "FAIL".yellow
|
73
|
-
end
|
74
|
-
failures.push fullResult
|
75
|
-
else
|
76
|
-
if html
|
77
|
-
puts "<td style='color: green; width: 10%; text-align:right;'>PASS</td></tr>"
|
78
|
-
else
|
79
|
-
puts "PASS".green
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
if html
|
85
|
-
print "</table></div>"
|
3
|
+
module Test
|
4
|
+
module Unit
|
5
|
+
class AutoRunner
|
6
|
+
RUNNERS[:monkey] = proc do |r|
|
7
|
+
require 'monkeytest/ui'
|
8
|
+
Test::Unit::UI::Monkey::TestRunner
|
86
9
|
end
|
87
10
|
end
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
print "TOTALS:".bold.ljust(38)
|
98
|
-
print "#{totalTests.to_s.rjust(4)} Tests "
|
99
|
-
print "#{totalAsserts.to_s.rjust(4)} Assertions "
|
100
|
-
print "#{(totalFailures+totalErrors).to_s.rjust(4)} Problem(s)\n"
|
101
|
-
end
|
102
|
-
if silent
|
103
|
-
if html
|
104
|
-
puts "</div>"
|
105
|
-
else
|
106
|
-
puts "\n"
|
107
|
-
end
|
108
|
-
elsif quiet
|
109
|
-
|
110
|
-
if html
|
111
|
-
puts "<div id='errors-failures' style=\"margin-top: 20px\"><div style='font-weight: bold;'>Errors & Failures</div>"
|
112
|
-
else
|
113
|
-
puts "\n\nErrors & Failures:".bold
|
114
|
-
end unless failures.empty?
|
115
|
-
|
116
|
-
puts "<table>" if html
|
117
|
-
failures.each do |badthing|
|
118
|
-
while matches = badthing.match(/(Error|Failure):[\s]+(test_[^\()]+)\(([^\)]+)\)([\s]\[[^\]]+\/(.+?):([\d]+)\])?/m) do
|
119
|
-
unless html
|
120
|
-
msg = " #{matches[1].ljust(10).red}" if matches[1] == "Error"
|
121
|
-
msg = " #{matches[1].ljust(10).yellow}" if matches[1] == "Failure"
|
122
|
-
msg << " #{matches[3].underline} : #{matches[2]}"
|
123
|
-
msg << " (#{matches[5]}:#{matches[6]})" unless matches[6].nil?
|
124
|
-
else
|
125
|
-
msg = "<tr>"
|
126
|
-
msg << "<td style=\"color:#FF0000; width: 10%\">#{matches[1]}</td>" if matches[1] == "Error"
|
127
|
-
msg << "<td style=\"color:#FFFF00; width: 10%\">#{matches[1]}</td>" if matches [1] == "Failure"
|
128
|
-
msg << "<td><u>#{matches[3]}</u> : #{matches[2]}"
|
129
|
-
msg << " (#{matches[5]}:#{matches[6]})" unless matches[6].nil?
|
130
|
-
msg << "</td></tr>"
|
131
|
-
end
|
132
|
-
puts msg
|
133
|
-
badthing = matches.post_match
|
134
|
-
end
|
135
|
-
end
|
136
|
-
if html
|
137
|
-
puts "</table></div>"
|
138
|
-
else
|
139
|
-
puts "\n"
|
140
|
-
end
|
141
|
-
else
|
142
|
-
if html
|
143
|
-
puts "<div id='errors-failures'><div style='font-weight: bold;'>Errors & Failures</div>" unless failures.empty?
|
144
|
-
else
|
145
|
-
puts "\n\nErrors & Failures:".bold unless failures.empty?
|
146
|
-
end
|
147
|
-
failures.each do |badthing|
|
148
|
-
if html
|
149
|
-
puts badthing
|
150
|
-
puts "</div>"
|
151
|
-
else
|
152
|
-
puts badthing
|
153
|
-
puts "\n"
|
154
|
-
end
|
155
|
-
if html
|
156
|
-
puts "</div>"
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
if html
|
161
|
-
puts "</div>"
|
162
|
-
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Monkey
|
15
|
+
# Warn users about the new way to test like a monkey
|
16
|
+
def self.run_tests(verbosity,output)
|
17
|
+
puts "As of Monkey Test 1.0.0 the use of rakefiles is no longer used. You can now run monkeytest as its own command line, monkeytest --help for a list of options."
|
18
|
+
puts "Don't forget to remove monkey.rake from lib/tasks of your rails project!"
|
19
|
+
exit!(0)
|
163
20
|
end
|
164
21
|
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
module MonkeyTest
|
6
|
+
class CLI
|
7
|
+
|
8
|
+
# Path to the test loader script
|
9
|
+
TESTLOADER = File.dirname(__FILE__) + '/test_loader.rb'
|
10
|
+
|
11
|
+
def self.fling!
|
12
|
+
new
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@options = parse_options
|
17
|
+
@cmd = build_cmd
|
18
|
+
fling!
|
19
|
+
end
|
20
|
+
|
21
|
+
def fling!
|
22
|
+
#puts @cmd
|
23
|
+
system @cmd
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_cmd
|
27
|
+
cmd = "ruby -rubygems -e \"require 'monkeytest'"
|
28
|
+
cmd << "; COLOR=#{@options.color}"
|
29
|
+
cmd << "; OUTPUT_LEVEL=:#{@options.outputLevel.to_s}"
|
30
|
+
cmd << "; OUTPUT_FORMAT=:#{@options.outputFormat.to_s}"
|
31
|
+
cmd << "; FILE=#{@options.outputFile}" unless @options.outputFile.nil?
|
32
|
+
cmd << "; FILE=nil" if @options.outputFile.nil?
|
33
|
+
cmd << "\" \"#{TESTLOADER}\" \"#{@options.testFiles.join('" "')}\" --runner=monkey"
|
34
|
+
return cmd
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_options(args=ARGV)
|
38
|
+
options = OpenStruct.new
|
39
|
+
|
40
|
+
# Setup default options
|
41
|
+
options.outputFormat = :console
|
42
|
+
options.outputLevel = :normal
|
43
|
+
options.color = true
|
44
|
+
if File.exists?("./test")
|
45
|
+
options.directory = Dir.new("./test")
|
46
|
+
else
|
47
|
+
options.directory = Dir.new(".")
|
48
|
+
end
|
49
|
+
options.pattern = /^.+_test\.rb$/
|
50
|
+
options.recursive = true
|
51
|
+
|
52
|
+
opts = OptionParser.new do |opts|
|
53
|
+
opts.banner = "Usage: monkeytest [options]"
|
54
|
+
|
55
|
+
# Options for specifying which tests will be run
|
56
|
+
opts.separator ""
|
57
|
+
opts.separator "Test selection criteria options:"
|
58
|
+
|
59
|
+
opts.on("-d DIRECTORY", "--directory DIRECTORY", "Run tests found in the given directory") { |dir|
|
60
|
+
begin
|
61
|
+
options.directory = Dir.new(dir)
|
62
|
+
rescue Exception => e
|
63
|
+
puts e
|
64
|
+
exit
|
65
|
+
end
|
66
|
+
}
|
67
|
+
|
68
|
+
opts.on("-d", "--directory DIRECTORY","Search DIRECTORY for tests") { |dir|
|
69
|
+
options.directory = Dir.new(dir)
|
70
|
+
}
|
71
|
+
|
72
|
+
opts.on("-r", "--[no-]recursive", "[Don't] Search directories recursively") { |r|
|
73
|
+
options.recursive = r
|
74
|
+
}
|
75
|
+
|
76
|
+
opts.on("-u", "--[no-]unit", "[Don't] Run unit tests") { |u|
|
77
|
+
options.unit = u
|
78
|
+
}
|
79
|
+
|
80
|
+
opts.on("-f", "--[no-]functional", "[Don't] Run functional tests") { |f|
|
81
|
+
options.functional = f
|
82
|
+
}
|
83
|
+
|
84
|
+
opts.on("-i", "--[no-]integration", "[Don't] Run integration tests") { |i|
|
85
|
+
options.integration = i
|
86
|
+
}
|
87
|
+
|
88
|
+
opts.on("-p PATTERN", "--pattern PATTERN", Regexp, "Run test files which match PATTERN\n#{' '*37}(use quotes for safety!)") { |regex|
|
89
|
+
options.pattern = regex
|
90
|
+
}
|
91
|
+
|
92
|
+
# Options for output
|
93
|
+
opts.separator ""
|
94
|
+
opts.separator "Output options:"
|
95
|
+
|
96
|
+
opts.on("-q", "--quiet", "Output summary of failures and errors only") { |q|
|
97
|
+
if options.outputLevel == :verbose
|
98
|
+
puts "Only one of --quiet or --verbose is allowed."
|
99
|
+
exit!(1)
|
100
|
+
end
|
101
|
+
options.outputLevel = :quiet
|
102
|
+
}
|
103
|
+
|
104
|
+
opts.on("-v", "--verbose", "Output full fault messages") { |s|
|
105
|
+
if options.outputLevel == :quiet
|
106
|
+
puts "Only one of --quiet or --verbose is allowed."
|
107
|
+
exit!(1)
|
108
|
+
end
|
109
|
+
options.outputLevel = :verbose
|
110
|
+
}
|
111
|
+
|
112
|
+
opts.on("--[no-]color", "[Don't] Show colored output") { |c|
|
113
|
+
options.color = c
|
114
|
+
}
|
115
|
+
|
116
|
+
#opts.on("--html", "--html [FILE]", "Output results in HTML\n#{' '*37}(optionally to the given file)") { |html|
|
117
|
+
# options.outputFormat = :html
|
118
|
+
# options.outputFile = html
|
119
|
+
#}
|
120
|
+
|
121
|
+
#opts.on("--rss", "--rss [FILE]", "Output results in RSS\n#{' '*37}(optionally to the given file)") { |rss|
|
122
|
+
# options.outputFormat = :rss
|
123
|
+
# options.outputFile = rss
|
124
|
+
#}
|
125
|
+
|
126
|
+
# Other options
|
127
|
+
opts.separator ""
|
128
|
+
opts.separator "Other options:"
|
129
|
+
opts.on("-h", "--help", "Displays this help message") {
|
130
|
+
puts opts
|
131
|
+
exit!(0)
|
132
|
+
}
|
133
|
+
|
134
|
+
opts.on("-V", "--version",
|
135
|
+
"Display monkey test version info"
|
136
|
+
) do
|
137
|
+
require 'monkeytest/version'
|
138
|
+
puts "Monkey Test v#{MonkeyTest::Version::STRING}"
|
139
|
+
exit!(0)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
begin
|
144
|
+
opts.parse!(args)
|
145
|
+
rescue OptionParser::MissingArgument => e
|
146
|
+
puts "Option #{e.to_s.match(/\-[\w]+/).to_s} is missing a required argument."
|
147
|
+
exit!(1)
|
148
|
+
rescue Exception => e
|
149
|
+
puts e
|
150
|
+
exit!(1)
|
151
|
+
end
|
152
|
+
|
153
|
+
options.testFiles = find_test_files(options)
|
154
|
+
if options.testFiles.empty?
|
155
|
+
puts "No test files were found with the given criteria."
|
156
|
+
exit!(0)
|
157
|
+
end
|
158
|
+
|
159
|
+
return options
|
160
|
+
end
|
161
|
+
|
162
|
+
def find_test_files(options)
|
163
|
+
files = []
|
164
|
+
if !options.unit.nil? or !options.integration.nil? or !options.functional.nil?
|
165
|
+
files.push find_files(Dir.new(options.directory.path + "/unit"), options.pattern) if File.exists?(options.directory.path + "/unit") unless options.unit.nil?
|
166
|
+
files.push find_files(Dir.new(options.directory.path + "/functional"), options.pattern) if File.exists?(options.directory.path + "/functional") unless options.functional.nil?
|
167
|
+
files.push find_files(Dir.new(options.directory.path + "/integration"), options.pattern) if File.exists?(options.directory.path + "/integration") unless options.integration.nil?
|
168
|
+
files.flatten!
|
169
|
+
elsif options.recursive
|
170
|
+
files = find_files_r(options.directory, options.pattern)
|
171
|
+
else
|
172
|
+
files = find_files(options.directory, options.pattern)
|
173
|
+
end
|
174
|
+
return files.flatten
|
175
|
+
end
|
176
|
+
|
177
|
+
def find_files_r(directory,pattern)
|
178
|
+
directories = directory.find_all { |f| !(f =~ /^\./) and File.directory?(directory.path + "/" + f) }
|
179
|
+
files = directory.find_all { |f| f =~ pattern and !File.directory?(directory.path + "/" + f) }
|
180
|
+
files.collect! { |f| directory.path + "/" + f }
|
181
|
+
if directories.empty?
|
182
|
+
return files
|
183
|
+
else
|
184
|
+
return(files.push directories.collect { |dir| find_files_r(Dir.new(directory.path + "/" + dir),pattern) })
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def find_files(directory,pattern)
|
189
|
+
files = directory.find_all { |f| f =~ pattern and !File.directory?(directory.path + "/" + f) }
|
190
|
+
files.collect { |f| directory.path + "/" + f }
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
require 'monkeytest/test'
|
3
|
+
|
4
|
+
module MonkeyTest
|
5
|
+
class TestClass
|
6
|
+
|
7
|
+
attr_accessor :name
|
8
|
+
attr_reader :tests
|
9
|
+
|
10
|
+
def initialize(name=nil)
|
11
|
+
@name = name
|
12
|
+
@tests = Hash.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_test(test)
|
16
|
+
return unless test.kind_of? MonkeyTest::Test and !test.name.nil? and @tests[test.name].nil?
|
17
|
+
@tests[test.name] = test
|
18
|
+
end
|
19
|
+
|
20
|
+
def worst
|
21
|
+
worst = "PASS"
|
22
|
+
@tests.each_value do |t|
|
23
|
+
worst = "FAIL" if t.status == "FAIL" and worst != "ERROR"
|
24
|
+
worst = "ERROR" if t.status == "ERROR"
|
25
|
+
end
|
26
|
+
return worst
|
27
|
+
end
|
28
|
+
|
29
|
+
# The same as: testClass.tests.each
|
30
|
+
def each_test
|
31
|
+
@tests.each_value do |t|
|
32
|
+
yield t
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def num_tests
|
37
|
+
@tests.size
|
38
|
+
end
|
39
|
+
|
40
|
+
def num_assertions
|
41
|
+
assertions = 0
|
42
|
+
@tests.each_value do |t|
|
43
|
+
assertions += t.assertions
|
44
|
+
end
|
45
|
+
return assertions
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
require 'monkeytest/testclass'
|
3
|
+
require 'monkeytest/test'
|
4
|
+
|
5
|
+
module MonkeyTest
|
6
|
+
class TestSuite
|
7
|
+
|
8
|
+
attr_accessor :name, :time
|
9
|
+
attr_reader :classes
|
10
|
+
|
11
|
+
def initialize(name=nil)
|
12
|
+
@name = name
|
13
|
+
@classes = Hash.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_class(aClass)
|
17
|
+
return unless aClass.kind_of? MonkeyTest::TestClass and !aClass.name.nil? and @classes[aClass.name].nil?
|
18
|
+
@classes[aClass.name] = aClass
|
19
|
+
end
|
20
|
+
|
21
|
+
# Same as testSuite.classes.each
|
22
|
+
def each_class
|
23
|
+
@classes.each_value do |c|
|
24
|
+
yield c
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def worst
|
29
|
+
worst = "PASS"
|
30
|
+
@classes.each_value do |c|
|
31
|
+
worst = "FAIL" if c.worst == "FAIL" and worst != "ERROR"
|
32
|
+
worst = "ERROR" if c.worst == "ERROR"
|
33
|
+
end
|
34
|
+
return worst
|
35
|
+
end
|
36
|
+
|
37
|
+
def num_classes
|
38
|
+
@classes.size
|
39
|
+
end
|
40
|
+
|
41
|
+
def num_tests
|
42
|
+
num = 0
|
43
|
+
@classes.each_value do |c|
|
44
|
+
num += c.tests.size
|
45
|
+
end
|
46
|
+
return num
|
47
|
+
end
|
48
|
+
|
49
|
+
def num_assertions
|
50
|
+
num = 0
|
51
|
+
@classes.each_value do |c|
|
52
|
+
num += c.num_assertions
|
53
|
+
end
|
54
|
+
return num
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
|
2
|
+
# Based on code written by Nathaniel Talbott
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test/unit/ui/testrunnermediator'
|
6
|
+
require 'test/unit/ui/testrunnerutilities'
|
7
|
+
require 'monkeytest/testsuite'
|
8
|
+
require 'ostruct'
|
9
|
+
|
10
|
+
module Test
|
11
|
+
module Unit
|
12
|
+
module UI
|
13
|
+
module Monkey
|
14
|
+
|
15
|
+
# Runs a Test::Unit::TestSuite on the console.
|
16
|
+
class TestRunner
|
17
|
+
extend TestRunnerUtilities
|
18
|
+
|
19
|
+
attr_accessor :noColor
|
20
|
+
|
21
|
+
# Creates a new TestRunner for running the passed
|
22
|
+
# suite. If quiet_mode is true, the output while
|
23
|
+
# running is limited to progress dots, errors and
|
24
|
+
# failures, and the final result. io specifies
|
25
|
+
# where runner output should go to; defaults to
|
26
|
+
# STDOUT.
|
27
|
+
def initialize(suite, outputLevel=:normal, io=nil)
|
28
|
+
@suite = suite
|
29
|
+
@suite = suite.suite if suite.respond_to?(:suite)
|
30
|
+
@outputLevel = :normal
|
31
|
+
@faults = Array.new
|
32
|
+
@results = MonkeyTest::TestSuite.new
|
33
|
+
@failed = false
|
34
|
+
@lastAssertionTotal = 0
|
35
|
+
end
|
36
|
+
|
37
|
+
# Begins the test run.
|
38
|
+
def start
|
39
|
+
setup_mediator
|
40
|
+
attach_to_mediator
|
41
|
+
case OUTPUT_FORMAT
|
42
|
+
when :console
|
43
|
+
require 'monkeytest/ui/console'
|
44
|
+
when :html
|
45
|
+
require 'monkeytest/ui/html'
|
46
|
+
end
|
47
|
+
return start_mediator
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def setup_mediator
|
52
|
+
@mediator = create_mediator(@suite)
|
53
|
+
suite_name = @suite.to_s
|
54
|
+
suite_name = @suite.name if @suite.kind_of?(Module)
|
55
|
+
@results.name = suite_name
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_mediator(suite)
|
59
|
+
return TestRunnerMediator.new(suite)
|
60
|
+
end
|
61
|
+
|
62
|
+
def attach_to_mediator
|
63
|
+
@mediator.add_listener(TestResult::FAULT, &method(:add_fault))
|
64
|
+
@mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
|
65
|
+
@mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
|
66
|
+
@mediator.add_listener(TestCase::STARTED, &method(:test_started))
|
67
|
+
@mediator.add_listener(TestCase::FINISHED, &method(:test_finished))
|
68
|
+
end
|
69
|
+
|
70
|
+
def start_mediator
|
71
|
+
return @mediator.run_suite
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_fault(fault)
|
75
|
+
if fault.kind_of? Test::Unit::Failure
|
76
|
+
@results.classes[@className].tests[@methodName].status = "FAIL"
|
77
|
+
@results.classes[@className].tests[@methodName].message = fault.message
|
78
|
+
@results.classes[@className].tests[@methodName].location = fault.location.first.match(/[^\/]+:[\d]+/).to_s
|
79
|
+
elsif fault.kind_of? Test::Unit::Error
|
80
|
+
@results.classes[@className].tests[@methodName].status = "ERROR"
|
81
|
+
@results.classes[@className].tests[@methodName].message = fault.exception
|
82
|
+
@results.classes[@className].tests[@methodName].location = fault.long_display.match(/([^\/]+?:[\d]+):in/)[1]
|
83
|
+
end
|
84
|
+
@results.classes[@className].tests[@methodName].fault = fault
|
85
|
+
@failed = true
|
86
|
+
end
|
87
|
+
|
88
|
+
def started(result)
|
89
|
+
@result = result
|
90
|
+
end
|
91
|
+
|
92
|
+
def finished(elapsed_time)
|
93
|
+
@results.time = elapsed_time
|
94
|
+
output(@results,OUTPUT_LEVEL,FILE,COLOR)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_started(name)
|
98
|
+
@className = name.match(/\((.+)\)/)[1]
|
99
|
+
@methodName = name.match(/^[^\(]+/).to_s
|
100
|
+
@results.add_class( MonkeyTest::TestClass.new(@className) )
|
101
|
+
@results.classes[@className].add_test( MonkeyTest::Test.new(@methodName) )
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_finished(name)
|
105
|
+
@results.classes[@className].tests[@methodName].assertions = @result.assertion_count - @lastAssertionTotal
|
106
|
+
@results.classes[@className].tests[@methodName].status = "PASS" unless (@failed)
|
107
|
+
@failed = false
|
108
|
+
@lastAssertionTotal = @result.assertion_count
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
if __FILE__ == $0
|
117
|
+
Test::Unit::UI::Console::TestRunner.start_command_line_test
|
118
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'monkeytest/ui'
|
2
|
+
require 'term/ansicolor'
|
3
|
+
include Term::ANSIColor
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'win32console'
|
7
|
+
include Win32::Console::ANSI
|
8
|
+
rescue Exception => e
|
9
|
+
# must be a *nix system or running cygwin, yay!
|
10
|
+
end
|
11
|
+
require 'pp'
|
12
|
+
|
13
|
+
module Test
|
14
|
+
module Unit
|
15
|
+
module UI
|
16
|
+
module Monkey
|
17
|
+
class TestRunner
|
18
|
+
private
|
19
|
+
|
20
|
+
def colorize(status)
|
21
|
+
return status.rjust(6) if @color == false
|
22
|
+
if status == "PASS"
|
23
|
+
return status.rjust(6).green
|
24
|
+
elsif status == "FAIL"
|
25
|
+
return status.rjust(6).yellow
|
26
|
+
elsif status == "ERROR"
|
27
|
+
return status.rjust(6).red
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def output(results,outputLevel=:normal,outFile=nil,color=true)
|
32
|
+
@color = color
|
33
|
+
|
34
|
+
puts "+------------------------------------------+-------+------------+--------+"
|
35
|
+
puts "| Test Class | Tests | Assertions | Status |"
|
36
|
+
puts "+------------------------------------------+-------+------------+--------+"
|
37
|
+
|
38
|
+
results.each_class do |c|
|
39
|
+
puts "| #{c.name.underline.ljust(48)} | #{c.num_tests.to_s.rjust(5)} | #{c.num_assertions.to_s.rjust(10)} | #{colorize(c.worst)} |"
|
40
|
+
end
|
41
|
+
puts "+------------------------------------------+-------+------------+--------+"
|
42
|
+
puts "| Total | #{results.num_tests.to_s.rjust(5)} | #{results.num_assertions.to_s.rjust(10)} | |"
|
43
|
+
puts "+------------------------------------------+-------+------------+--------+"
|
44
|
+
puts "Finished in #{results.time} seconds"
|
45
|
+
|
46
|
+
# Error & Failors Summary
|
47
|
+
unless outputLevel == :quiet
|
48
|
+
puts "\n\nErrors & Failures:" unless results.worst == "PASS"
|
49
|
+
results.each_class do |c|
|
50
|
+
c.each_test do |t|
|
51
|
+
unless t.passed?
|
52
|
+
print "#{c.name.underline}::#{t.name} (#{t.location})".ljust(69)
|
53
|
+
puts colorize(t.status).rjust(5)
|
54
|
+
if outputLevel == :normal
|
55
|
+
puts "#{t.message.to_s.gsub(/[\n][\s]+/,' ')}\n\n"
|
56
|
+
elsif outputLevel == :verbose
|
57
|
+
puts "#{t.fault}\n\n"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
metadata
CHANGED
@@ -3,9 +3,9 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: monkeytest
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-
|
8
|
-
summary: A
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2006-12-15 00:00:00 -05:00
|
8
|
+
summary: A command line tool for at-a-glance testing.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: geoffrey.parsons@gmail.com & mwhuss@gmail.com
|
@@ -20,7 +20,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 1.8.
|
23
|
+
version: 1.8.5
|
24
24
|
version:
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
@@ -29,8 +29,15 @@ post_install_message:
|
|
29
29
|
authors:
|
30
30
|
- Geoff Parsons & Marshall Huss
|
31
31
|
files:
|
32
|
-
- lib/tasks/monkey.rake
|
33
32
|
- lib/monkeytest.rb
|
33
|
+
- lib/monkeytest/cli.rb
|
34
|
+
- lib/monkeytest/test_loader.rb
|
35
|
+
- lib/monkeytest/testsuite.rb
|
36
|
+
- lib/monkeytest/testclass.rb
|
37
|
+
- lib/monkeytest/test.rb
|
38
|
+
- lib/monkeytest/ui.rb
|
39
|
+
- lib/monkeytest/ui/console.rb
|
40
|
+
- lib/monkeytest/version.rb
|
34
41
|
test_files: []
|
35
42
|
|
36
43
|
rdoc_options: []
|
data/lib/tasks/monkey.rake
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
# ===================================================
|
2
|
-
# A set of rake tasks for running monkey tests.
|
3
|
-
# created with monkeytest 0.2
|
4
|
-
# ===================================================
|
5
|
-
|
6
|
-
begin
|
7
|
-
require 'rubygems'
|
8
|
-
rescue
|
9
|
-
puts "Please install ruby gems."
|
10
|
-
exit(1)
|
11
|
-
end
|
12
|
-
|
13
|
-
begin
|
14
|
-
require 'win32console'
|
15
|
-
include Win32::Console::ANSI
|
16
|
-
rescue Exception => e
|
17
|
-
puts "When running on Windows the win32console gem is required."
|
18
|
-
exit(1)
|
19
|
-
end unless system('ls > /dev/null 2> /dev/null')
|
20
|
-
|
21
|
-
begin
|
22
|
-
require 'term/ansicolor'
|
23
|
-
include Term::ANSIColor
|
24
|
-
rescue Exception => e
|
25
|
-
puts "The term-ansicolor gem is required to perform this task."
|
26
|
-
exit(1)
|
27
|
-
end
|
28
|
-
|
29
|
-
begin
|
30
|
-
require 'monkeytest'
|
31
|
-
rescue Exception => e
|
32
|
-
puts "The monkeytest gem is required to perform this task."
|
33
|
-
exit(1)
|
34
|
-
end
|
35
|
-
|
36
|
-
namespace :test do
|
37
|
-
|
38
|
-
namespace :monkey do
|
39
|
-
|
40
|
-
namespace :silent do
|
41
|
-
desc "Outputs per-file summary only in HTML."
|
42
|
-
task :html do
|
43
|
-
Monkey.run_tests(:silent, true)
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
namespace :quiet do
|
49
|
-
desc "Outputs per-file summary as well as a method level summaries in HTML."
|
50
|
-
task :html do
|
51
|
-
Monkey.run_tests(:quiet, true)
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
desc "Outputs per-file summary only."
|
57
|
-
task :silent do
|
58
|
-
Monkey.run_tests(:silent, false)
|
59
|
-
end
|
60
|
-
|
61
|
-
desc "Outputs per-file summary as well as a method level summaries."
|
62
|
-
task :quiet do
|
63
|
-
Monkey.run_tests(:quiet, false)
|
64
|
-
end
|
65
|
-
|
66
|
-
desc "Outputs per-file summary as well as full failure messages in HTML."
|
67
|
-
task :html do
|
68
|
-
Monkey.run_tests(:normal, true)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
desc "Outputs per-file summary as well as full failure messages."
|
73
|
-
task :monkey do
|
74
|
-
Monkey.run_tests(:normal, false)
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|