monkeytest 0.2.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|