stopdropandrew_ci_reporter 1.7.0.1
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/History.txt +166 -0
- data/LICENSE.txt +21 -0
- data/Manifest.txt +32 -0
- data/README.rdoc +67 -0
- data/Rakefile +120 -0
- data/lib/ci/reporter/core.rb +6 -0
- data/lib/ci/reporter/cucumber.rb +125 -0
- data/lib/ci/reporter/minitest.rb +224 -0
- data/lib/ci/reporter/rake/cucumber.rb +19 -0
- data/lib/ci/reporter/rake/cucumber_loader.rb +6 -0
- data/lib/ci/reporter/rake/minitest.rb +15 -0
- data/lib/ci/reporter/rake/minitest_loader.rb +9 -0
- data/lib/ci/reporter/rake/rspec.rb +31 -0
- data/lib/ci/reporter/rake/rspec_loader.rb +6 -0
- data/lib/ci/reporter/rake/test_unit.rb +15 -0
- data/lib/ci/reporter/rake/test_unit_loader.rb +36 -0
- data/lib/ci/reporter/rake/utils.rb +14 -0
- data/lib/ci/reporter/report_manager.rb +63 -0
- data/lib/ci/reporter/rspec.rb +227 -0
- data/lib/ci/reporter/test_suite.rb +156 -0
- data/lib/ci/reporter/test_unit.rb +143 -0
- data/lib/ci/reporter/version.rb +11 -0
- data/spec/ci/reporter/cucumber_spec.rb +230 -0
- data/spec/ci/reporter/output_capture_spec.rb +57 -0
- data/spec/ci/reporter/rake/rake_tasks_spec.rb +105 -0
- data/spec/ci/reporter/report_manager_spec.rb +62 -0
- data/spec/ci/reporter/rspec_spec.rb +152 -0
- data/spec/ci/reporter/test_suite_spec.rb +160 -0
- data/spec/ci/reporter/test_unit_spec.rb +152 -0
- data/spec/spec_helper.rb +23 -0
- data/stub.rake +15 -0
- data/tasks/ci_reporter.rake +20 -0
- metadata +173 -0
@@ -0,0 +1,227 @@
|
|
1
|
+
# Copyright (c) 2006-2012 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require 'ci/reporter/core'
|
6
|
+
|
7
|
+
module CI
|
8
|
+
module Reporter
|
9
|
+
module RSpecFormatters
|
10
|
+
begin
|
11
|
+
require 'rspec/core/formatters/base_formatter'
|
12
|
+
require 'rspec/core/formatters/progress_formatter'
|
13
|
+
require 'rspec/core/formatters/documentation_formatter'
|
14
|
+
BaseFormatter = ::RSpec::Core::Formatters::BaseFormatter
|
15
|
+
ProgressFormatter = ::RSpec::Core::Formatters::ProgressFormatter
|
16
|
+
DocFormatter = ::RSpec::Core::Formatters::DocumentationFormatter
|
17
|
+
rescue LoadError => first_error
|
18
|
+
begin
|
19
|
+
require 'spec/runner/formatter/progress_bar_formatter'
|
20
|
+
require 'spec/runner/formatter/specdoc_formatter'
|
21
|
+
BaseFormatter = ::Spec::Runner::Formatter::BaseFormatter
|
22
|
+
ProgressFormatter = ::Spec::Runner::Formatter::ProgressBarFormatter
|
23
|
+
DocFormatter = ::Spec::Runner::Formatter::SpecdocFormatter
|
24
|
+
rescue LoadError
|
25
|
+
raise first_error
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Wrapper around a <code>RSpec</code> error or failure to be used by the test suite to interpret results.
|
31
|
+
class RSpecFailure
|
32
|
+
attr_reader :exception
|
33
|
+
def initialize(failure)
|
34
|
+
@failure = failure
|
35
|
+
@exception = failure.exception
|
36
|
+
end
|
37
|
+
|
38
|
+
def failure?
|
39
|
+
@failure.expectation_not_met?
|
40
|
+
end
|
41
|
+
|
42
|
+
def error?
|
43
|
+
!failure?
|
44
|
+
end
|
45
|
+
|
46
|
+
def name() @example.metadata[:execution_result][:exception].class.name end
|
47
|
+
def message() @example.metadata[:execution_result][:exception].message end
|
48
|
+
def location() @example.metadata[:execution_result][:exception].backtrace.join("\n") end
|
49
|
+
end
|
50
|
+
|
51
|
+
class RSpec2Failure < RSpecFailure
|
52
|
+
def initialize(example, formatter)
|
53
|
+
@formatter = formatter
|
54
|
+
@example = example
|
55
|
+
@exception = @example.execution_result[:exception] || @example.execution_result[:exception_encountered]
|
56
|
+
end
|
57
|
+
|
58
|
+
def name
|
59
|
+
@exception.class.name
|
60
|
+
end
|
61
|
+
|
62
|
+
def message
|
63
|
+
@exception.message
|
64
|
+
end
|
65
|
+
|
66
|
+
def failure?
|
67
|
+
exception.is_a?(::RSpec::Expectations::ExpectationNotMetError)
|
68
|
+
end
|
69
|
+
|
70
|
+
def location
|
71
|
+
output = []
|
72
|
+
output.push "#{exception.class.name << ":"}" unless exception.class.name =~ /RSpec/
|
73
|
+
output.push @exception.message
|
74
|
+
|
75
|
+
[@formatter.format_backtrace(@exception.backtrace, @example)].flatten.each do |backtrace_info|
|
76
|
+
backtrace_info.lines.each do |line|
|
77
|
+
output.push " #{line}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
output.join "\n"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Custom +RSpec+ formatter used to hook into the spec runs and capture results.
|
85
|
+
class RSpec < RSpecFormatters::BaseFormatter
|
86
|
+
attr_accessor :report_manager
|
87
|
+
attr_accessor :formatter
|
88
|
+
def initialize(*args)
|
89
|
+
super
|
90
|
+
@formatter ||= RSpecFormatters::ProgressFormatter.new(*args)
|
91
|
+
@report_manager = ReportManager.new("spec")
|
92
|
+
@suite = nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def start(spec_count)
|
96
|
+
@formatter.start(spec_count)
|
97
|
+
end
|
98
|
+
|
99
|
+
# rspec 0.9
|
100
|
+
def add_behaviour(name)
|
101
|
+
@formatter.add_behaviour(name)
|
102
|
+
new_suite(name)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Compatibility with rspec < 1.2.4
|
106
|
+
def add_example_group(example_group)
|
107
|
+
@formatter.add_example_group(example_group)
|
108
|
+
new_suite(description_for(example_group))
|
109
|
+
end
|
110
|
+
|
111
|
+
# rspec >= 1.2.4
|
112
|
+
def example_group_started(example_group)
|
113
|
+
@formatter.example_group_started(example_group)
|
114
|
+
new_suite(description_for(example_group))
|
115
|
+
end
|
116
|
+
|
117
|
+
def example_group_finished(example_group)
|
118
|
+
@formatter.example_group_finished(example_group)
|
119
|
+
end
|
120
|
+
|
121
|
+
def example_started(name_or_example)
|
122
|
+
@formatter.example_started(name_or_example)
|
123
|
+
spec = TestCase.new
|
124
|
+
@suite.testcases << spec
|
125
|
+
spec.start
|
126
|
+
end
|
127
|
+
|
128
|
+
def example_failed(name_or_example, *rest)
|
129
|
+
@formatter.example_failed(name_or_example, *rest)
|
130
|
+
|
131
|
+
# In case we fail in before(:all)
|
132
|
+
example_started(name_or_example) if @suite.testcases.empty?
|
133
|
+
|
134
|
+
if name_or_example.respond_to?(:execution_result) # RSpec 2
|
135
|
+
failure = RSpec2Failure.new(name_or_example, @formatter)
|
136
|
+
else
|
137
|
+
failure = RSpecFailure.new(rest[1]) # example_failed(name, counter, failure) in RSpec 1
|
138
|
+
end
|
139
|
+
|
140
|
+
spec = @suite.testcases.last
|
141
|
+
spec.finish
|
142
|
+
spec.name = description_for(name_or_example)
|
143
|
+
spec.failures << failure
|
144
|
+
end
|
145
|
+
|
146
|
+
def example_passed(name_or_example)
|
147
|
+
@formatter.example_passed(name_or_example)
|
148
|
+
spec = @suite.testcases.last
|
149
|
+
spec.finish
|
150
|
+
spec.name = description_for(name_or_example)
|
151
|
+
end
|
152
|
+
|
153
|
+
def example_pending(*args)
|
154
|
+
@formatter.example_pending(*args)
|
155
|
+
name = description_for(args[0])
|
156
|
+
spec = @suite.testcases.last
|
157
|
+
spec.finish
|
158
|
+
spec.name = "#{name} (PENDING)"
|
159
|
+
spec.skipped = true
|
160
|
+
end
|
161
|
+
|
162
|
+
def start_dump
|
163
|
+
@formatter.start_dump
|
164
|
+
end
|
165
|
+
|
166
|
+
def dump_failures(*args)
|
167
|
+
@formatter.dump_failures(*args)
|
168
|
+
end
|
169
|
+
|
170
|
+
def dump_failure(*args)
|
171
|
+
@formatter.dump_failure(*args)
|
172
|
+
end
|
173
|
+
|
174
|
+
def dump_summary(*args)
|
175
|
+
@formatter.dump_summary(*args)
|
176
|
+
write_report
|
177
|
+
@formatter.dump_failures
|
178
|
+
end
|
179
|
+
|
180
|
+
def dump_pending
|
181
|
+
@formatter.dump_pending
|
182
|
+
end
|
183
|
+
|
184
|
+
def close
|
185
|
+
@formatter.close
|
186
|
+
end
|
187
|
+
|
188
|
+
private
|
189
|
+
def description_for(name_or_example)
|
190
|
+
if name_or_example.respond_to?(:full_description)
|
191
|
+
name_or_example.full_description
|
192
|
+
elsif name_or_example.respond_to?(:metadata)
|
193
|
+
name_or_example.metadata[:example_group][:full_description]
|
194
|
+
elsif name_or_example.respond_to?(:description)
|
195
|
+
name_or_example.description
|
196
|
+
else
|
197
|
+
"UNKNOWN"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def write_report
|
202
|
+
@suite.finish
|
203
|
+
@report_manager.write_report(@suite)
|
204
|
+
end
|
205
|
+
|
206
|
+
def new_suite(name)
|
207
|
+
write_report if @suite
|
208
|
+
@suite = TestSuite.new name
|
209
|
+
@suite.start
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
class RSpecDoc < RSpec
|
214
|
+
def initialize(*args)
|
215
|
+
@formatter = RSpecFormatters::DocFormatter.new(*args)
|
216
|
+
super
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
class RSpecBase < RSpec
|
221
|
+
def initialize(*args)
|
222
|
+
@formatter = RSpecFormatters::BaseFormatter.new(*args)
|
223
|
+
super
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# Copyright (c) 2006-2012 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require 'delegate'
|
6
|
+
require 'stringio'
|
7
|
+
|
8
|
+
module CI
|
9
|
+
module Reporter
|
10
|
+
# Emulates/delegates IO to $stdout or $stderr in order to capture output to report in the XML file.
|
11
|
+
class OutputCapture < DelegateClass(IO)
|
12
|
+
# Start capturing IO, using the given block to assign self to the proper IO global.
|
13
|
+
def initialize(io, &assign)
|
14
|
+
super
|
15
|
+
@delegate_io = io
|
16
|
+
@captured_io = StringIO.new
|
17
|
+
@assign_block = assign
|
18
|
+
@assign_block.call self
|
19
|
+
end
|
20
|
+
|
21
|
+
# Finalize the capture and reset to the original IO object.
|
22
|
+
def finish
|
23
|
+
@assign_block.call @delegate_io
|
24
|
+
@captured_io.string
|
25
|
+
end
|
26
|
+
|
27
|
+
# setup tee methods
|
28
|
+
%w(<< print printf putc puts write).each do |m|
|
29
|
+
module_eval(<<-EOS, __FILE__, __LINE__)
|
30
|
+
def #{m}(*args, &block)
|
31
|
+
@delegate_io.send(:#{m}, *args, &block)
|
32
|
+
@captured_io.send(:#{m}, *args, &block)
|
33
|
+
end
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Basic structure representing the running of a test suite. Used to time tests and store results.
|
39
|
+
class TestSuite < Struct.new(:name, :tests, :time, :failures, :errors, :skipped, :assertions)
|
40
|
+
attr_accessor :testcases
|
41
|
+
attr_accessor :stdout, :stderr
|
42
|
+
def initialize(name)
|
43
|
+
super(name.to_s) # RSpec passes a "description" object instead of a string
|
44
|
+
@testcases = []
|
45
|
+
end
|
46
|
+
|
47
|
+
# Starts timing the test suite.
|
48
|
+
def start
|
49
|
+
@start = Time.now
|
50
|
+
unless ENV['CI_CAPTURE'] == "off"
|
51
|
+
@capture_out = OutputCapture.new($stdout) {|io| $stdout = io }
|
52
|
+
@capture_err = OutputCapture.new($stderr) {|io| $stderr = io }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Finishes timing the test suite.
|
57
|
+
def finish
|
58
|
+
self.tests = testcases.size
|
59
|
+
self.time = Time.now - @start
|
60
|
+
self.failures = testcases.inject(0) {|sum,tc| sum += tc.failures.select{|f| f.failure? }.size }
|
61
|
+
self.errors = testcases.inject(0) {|sum,tc| sum += tc.failures.select{|f| f.error? }.size }
|
62
|
+
self.skipped = testcases.inject(0) {|sum,tc| sum += (tc.skipped? ? 1 : 0) }
|
63
|
+
self.stdout = @capture_out.finish if @capture_out
|
64
|
+
self.stderr = @capture_err.finish if @capture_err
|
65
|
+
end
|
66
|
+
|
67
|
+
# Creates the xml builder instance used to create the report xml document.
|
68
|
+
def create_builder
|
69
|
+
require 'builder'
|
70
|
+
# :escape_attrs is obsolete in a newer version, but should do no harm
|
71
|
+
Builder::XmlMarkup.new(:indent => 2, :escape_attrs => true)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Creates an xml string containing the test suite results.
|
75
|
+
def to_xml
|
76
|
+
builder = create_builder
|
77
|
+
# more recent version of Builder doesn't need the escaping
|
78
|
+
def builder.trunc!(txt)
|
79
|
+
txt.sub(/\n.*/m, '...')
|
80
|
+
end
|
81
|
+
builder.instruct!
|
82
|
+
attrs = {}
|
83
|
+
each_pair {|k,v| attrs[k] = builder.trunc!(v.to_s) unless v.nil? || v.to_s.empty? }
|
84
|
+
builder.testsuite(attrs) do
|
85
|
+
@testcases.each do |tc|
|
86
|
+
tc.to_xml(builder)
|
87
|
+
end
|
88
|
+
builder.tag! "system-out" do
|
89
|
+
builder.text!(self.stdout || '' )
|
90
|
+
end
|
91
|
+
builder.tag! "system-err" do
|
92
|
+
builder.text!(self.stderr || '' )
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Structure used to represent an individual test case. Used to time the test and store the result.
|
99
|
+
class TestCase < Struct.new(:name, :time, :assertions)
|
100
|
+
attr_accessor :failures
|
101
|
+
attr_accessor :skipped
|
102
|
+
|
103
|
+
def initialize(*args)
|
104
|
+
super
|
105
|
+
@failures = []
|
106
|
+
end
|
107
|
+
|
108
|
+
# Starts timing the test.
|
109
|
+
def start
|
110
|
+
@start = Time.now
|
111
|
+
end
|
112
|
+
|
113
|
+
# Finishes timing the test.
|
114
|
+
def finish
|
115
|
+
self.time = Time.now - @start
|
116
|
+
end
|
117
|
+
|
118
|
+
# Returns non-nil if the test failed.
|
119
|
+
def failure?
|
120
|
+
!failures.empty? && failures.detect {|f| f.failure? }
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns non-nil if the test had an error.
|
124
|
+
def error?
|
125
|
+
!failures.empty? && failures.detect {|f| f.error? }
|
126
|
+
end
|
127
|
+
|
128
|
+
def skipped?
|
129
|
+
return skipped
|
130
|
+
end
|
131
|
+
|
132
|
+
# Writes xml representing the test result to the provided builder.
|
133
|
+
def to_xml(builder)
|
134
|
+
attrs = {}
|
135
|
+
each_pair {|k,v| attrs[k] = builder.trunc!(v.to_s) unless v.nil? || v.to_s.empty?}
|
136
|
+
builder.testcase(attrs) do
|
137
|
+
if skipped
|
138
|
+
builder.skipped
|
139
|
+
else
|
140
|
+
failures.each do |failure|
|
141
|
+
tag = case failure.class.name
|
142
|
+
when /TestUnitSkipped/ then :skipped
|
143
|
+
when /TestUnitError/, /MiniTestError/ then :error
|
144
|
+
else :failure end
|
145
|
+
|
146
|
+
builder.tag!(tag, :type => builder.trunc!(failure.name), :message => builder.trunc!(failure.message)) do
|
147
|
+
builder.text!(failure.message + " (#{failure.name})\n")
|
148
|
+
builder.text!(failure.location)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# Copyright (c) 2006-2012 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require 'ci/reporter/core'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'test/unit/ui/console/testrunner'
|
8
|
+
|
9
|
+
module CI
|
10
|
+
module Reporter
|
11
|
+
# Factory for constructing either a CI::Reporter::TestUnitFailure or CI::Reporter::TestUnitError depending on the result
|
12
|
+
# of the test.
|
13
|
+
class Failure
|
14
|
+
def self.new(fault)
|
15
|
+
return TestUnitFailure.new(fault) if fault.kind_of?(Test::Unit::Failure)
|
16
|
+
return TestUnitSkipped.new(fault) if Test::Unit.constants.include?("Omission") && (fault.kind_of?(Test::Unit::Omission) || fault.kind_of?(Test::Unit::Pending))
|
17
|
+
return TestUnitNotification.new(fault) if Test::Unit.constants.include?("Notification") && fault.kind_of?(Test::Unit::Notification)
|
18
|
+
TestUnitError.new(fault)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Wrapper around a <code>Test::Unit</code> error to be used by the test suite to interpret results.
|
23
|
+
class TestUnitError
|
24
|
+
def initialize(fault) @fault = fault end
|
25
|
+
def failure?() false end
|
26
|
+
def error?() true end
|
27
|
+
def name() @fault.exception.class.name end
|
28
|
+
def message() @fault.exception.message end
|
29
|
+
def location() @fault.exception.backtrace.join("\n") end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Wrapper around a <code>Test::Unit</code> failure to be used by the test suite to interpret results.
|
33
|
+
class TestUnitFailure
|
34
|
+
def initialize(fault) @fault = fault end
|
35
|
+
def failure?() true end
|
36
|
+
def error?() false end
|
37
|
+
def name() Test::Unit::AssertionFailedError.name end
|
38
|
+
def message() @fault.message end
|
39
|
+
def location() @fault.location.join("\n") end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Wrapper around a <code>Test::Unit</code> 2.0 omission.
|
43
|
+
class TestUnitSkipped
|
44
|
+
def initialize(fault) @fault = fault end
|
45
|
+
def failure?() false end
|
46
|
+
def error?() false end
|
47
|
+
def name() @fault.class.name end
|
48
|
+
def message() @fault.message end
|
49
|
+
def location() @fault.location.join("\n") end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Wrapper around a <code>Test::Unit</code> 2.0 notification.
|
53
|
+
class TestUnitNotification
|
54
|
+
def initialize(fault) @fault = fault end
|
55
|
+
def failure?() false end
|
56
|
+
def error?() false end
|
57
|
+
def name() @fault.class.name end
|
58
|
+
def message() @fault.message end
|
59
|
+
def location() @fault.location.join("\n") end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Replacement Mediator that adds listeners to capture the results of the <code>Test::Unit</code> runs.
|
63
|
+
class TestUnit < Test::Unit::UI::TestRunnerMediator
|
64
|
+
def initialize(suite, report_mgr = nil)
|
65
|
+
super(suite)
|
66
|
+
@report_manager = report_mgr || ReportManager.new("test")
|
67
|
+
add_listener(Test::Unit::UI::TestRunnerMediator::STARTED, &method(:started))
|
68
|
+
add_listener(Test::Unit::TestCase::STARTED, &method(:test_started))
|
69
|
+
add_listener(Test::Unit::TestCase::FINISHED, &method(:test_finished))
|
70
|
+
add_listener(Test::Unit::TestResult::FAULT, &method(:fault))
|
71
|
+
add_listener(Test::Unit::UI::TestRunnerMediator::FINISHED, &method(:finished))
|
72
|
+
end
|
73
|
+
|
74
|
+
def started(result)
|
75
|
+
@suite_result = result
|
76
|
+
@last_assertion_count = 0
|
77
|
+
@current_suite = nil
|
78
|
+
@unknown_count = 0
|
79
|
+
@result_assertion_count = 0
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_started(name)
|
83
|
+
test_name, suite_name = extract_names(name)
|
84
|
+
unless @current_suite && @current_suite.name == suite_name
|
85
|
+
finish_suite
|
86
|
+
start_suite(suite_name)
|
87
|
+
end
|
88
|
+
start_test(test_name)
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_finished(name)
|
92
|
+
finish_test
|
93
|
+
end
|
94
|
+
|
95
|
+
def fault(fault)
|
96
|
+
tc = @current_suite.testcases.last
|
97
|
+
tc.failures << Failure.new(fault)
|
98
|
+
end
|
99
|
+
|
100
|
+
def finished(elapsed_time)
|
101
|
+
finish_suite
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
def extract_names(name)
|
106
|
+
match = name.match(/(.*)\(([^)]*)\)/)
|
107
|
+
if match
|
108
|
+
[match[1], match[2]]
|
109
|
+
else
|
110
|
+
@unknown_count += 1
|
111
|
+
[name, "unknown-#{@unknown_count}"]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def start_suite(suite_name)
|
116
|
+
@current_suite = TestSuite.new(suite_name)
|
117
|
+
@current_suite.start
|
118
|
+
end
|
119
|
+
|
120
|
+
def finish_suite
|
121
|
+
if @current_suite
|
122
|
+
@current_suite.finish
|
123
|
+
@current_suite.assertions = @suite_result.assertion_count - @last_assertion_count
|
124
|
+
@last_assertion_count = @suite_result.assertion_count
|
125
|
+
@report_manager.write_report(@current_suite)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def start_test(test_name)
|
130
|
+
tc = TestCase.new(test_name)
|
131
|
+
tc.start
|
132
|
+
@current_suite.testcases << tc
|
133
|
+
end
|
134
|
+
|
135
|
+
def finish_test
|
136
|
+
tc = @current_suite.testcases.last
|
137
|
+
tc.finish
|
138
|
+
tc.assertions = @suite_result.assertion_count - @result_assertion_count
|
139
|
+
@result_assertion_count = @suite_result.assertion_count
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|