finnlabs-ci_reporter 1.6.5
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 +136 -0
- data/LICENSE.txt +21 -0
- data/Manifest.txt +29 -0
- data/README.txt +65 -0
- data/Rakefile +101 -0
- data/lib/ci/reporter/core.rb +6 -0
- data/lib/ci/reporter/cucumber.rb +120 -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/rspec.rb +25 -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 +21 -0
- data/lib/ci/reporter/rake/utils.rb +14 -0
- data/lib/ci/reporter/report_manager.rb +34 -0
- data/lib/ci/reporter/rspec.rb +189 -0
- data/lib/ci/reporter/test_suite.rb +151 -0
- data/lib/ci/reporter/test_unit.rb +132 -0
- data/lib/ci/reporter/version.rb +5 -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 +100 -0
- data/spec/ci/reporter/report_manager_spec.rb +51 -0
- data/spec/ci/reporter/rspec_spec.rb +146 -0
- data/spec/ci/reporter/test_suite_spec.rb +151 -0
- data/spec/ci/reporter/test_unit_spec.rb +152 -0
- data/spec/spec_helper.rb +21 -0
- data/stub.rake +14 -0
- data/tasks/ci_reporter.rake +18 -0
- metadata +124 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
# Copyright (c) 2006-2010 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + "/../../spec_helper.rb"
|
6
|
+
require 'rexml/document'
|
7
|
+
|
8
|
+
describe "Output capture" do
|
9
|
+
before(:each) do
|
10
|
+
@suite = CI::Reporter::TestSuite.new "test"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should save stdout and stderr messages written during the test run" do
|
14
|
+
@suite.start
|
15
|
+
puts "Hello"
|
16
|
+
$stderr.print "Hi"
|
17
|
+
@suite.finish
|
18
|
+
@suite.stdout.should == "Hello\n"
|
19
|
+
@suite.stderr.should == "Hi"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should include system-out and system-err elements in the xml output" do
|
23
|
+
@suite.start
|
24
|
+
puts "Hello"
|
25
|
+
$stderr.print "Hi"
|
26
|
+
@suite.finish
|
27
|
+
|
28
|
+
root = REXML::Document.new(@suite.to_xml).root
|
29
|
+
root.elements.to_a('//system-out').length.should == 1
|
30
|
+
root.elements.to_a('//system-err').length.should == 1
|
31
|
+
root.elements.to_a('//system-out').first.texts.first.to_s.strip.should == "Hello"
|
32
|
+
root.elements.to_a('//system-err').first.texts.first.to_s.strip.should == "Hi"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return $stdout and $stderr to original value after finish" do
|
36
|
+
out, err = $stdout, $stderr
|
37
|
+
@suite.start
|
38
|
+
$stdout.object_id.should_not == out.object_id
|
39
|
+
$stderr.object_id.should_not == err.object_id
|
40
|
+
@suite.finish
|
41
|
+
$stdout.object_id.should == out.object_id
|
42
|
+
$stderr.object_id.should == err.object_id
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should capture only during run of owner test suite" do
|
46
|
+
$stdout.print "A"
|
47
|
+
$stderr.print "A"
|
48
|
+
@suite.start
|
49
|
+
$stdout.print "B"
|
50
|
+
$stderr.print "B"
|
51
|
+
@suite.finish
|
52
|
+
$stdout.print "C"
|
53
|
+
$stderr.print "C"
|
54
|
+
@suite.stdout.should == "B"
|
55
|
+
@suite.stderr.should == "B"
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# Copyright (c) 2006-2010 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + "/../../../spec_helper.rb"
|
6
|
+
require 'rake'
|
7
|
+
|
8
|
+
def save_env(v)
|
9
|
+
ENV["PREV_#{v}"] = ENV[v]
|
10
|
+
end
|
11
|
+
def restore_env(v)
|
12
|
+
ENV[v] = ENV["PREV_#{v}"]
|
13
|
+
ENV.delete("PREV_#{v}")
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "ci_reporter ci:setup:testunit task" do
|
17
|
+
before(:each) do
|
18
|
+
@rake = Rake::Application.new
|
19
|
+
Rake.application = @rake
|
20
|
+
load CI_REPORTER_LIB + '/ci/reporter/rake/test_unit.rb'
|
21
|
+
save_env "CI_REPORTS"
|
22
|
+
save_env "TESTOPTS"
|
23
|
+
ENV["CI_REPORTS"] = "some-bogus-nonexistent-directory-that-wont-fail-rm_rf"
|
24
|
+
end
|
25
|
+
after(:each) do
|
26
|
+
restore_env "TESTOPTS"
|
27
|
+
restore_env "CI_REPORTS"
|
28
|
+
Rake.application = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should set ENV['TESTOPTS'] to include test/unit setup file" do
|
32
|
+
@rake["ci:setup:testunit"].invoke
|
33
|
+
ENV["TESTOPTS"].should =~ /test_unit_loader/
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should append to ENV['TESTOPTS'] if it already contains a value" do
|
37
|
+
ENV["TESTOPTS"] = "somevalue".freeze
|
38
|
+
@rake["ci:setup:testunit"].invoke
|
39
|
+
ENV["TESTOPTS"].should =~ /somevalue.*test_unit_loader/
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "ci_reporter ci:setup:rspec task" do
|
44
|
+
before(:each) do
|
45
|
+
@rake = Rake::Application.new
|
46
|
+
Rake.application = @rake
|
47
|
+
load CI_REPORTER_LIB + '/ci/reporter/rake/rspec.rb'
|
48
|
+
save_env "CI_REPORTS"
|
49
|
+
save_env "SPEC_OPTS"
|
50
|
+
ENV["CI_REPORTS"] = "some-bogus-nonexistent-directory-that-wont-fail-rm_rf"
|
51
|
+
end
|
52
|
+
after(:each) do
|
53
|
+
restore_env "SPEC_OPTS"
|
54
|
+
restore_env "CI_REPORTS"
|
55
|
+
Rake.application = nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should set ENV['SPEC_OPTS'] to include rspec formatter args" do
|
59
|
+
@rake["ci:setup:rspec"].invoke
|
60
|
+
ENV["SPEC_OPTS"].should =~ /--require.*rspec_loader.*--format.*CI::Reporter::RSpec/
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should set ENV['SPEC_OPTS'] to include rspec doc formatter if task is ci:setup:rspecdoc" do
|
64
|
+
@rake["ci:setup:rspecdoc"].invoke
|
65
|
+
ENV["SPEC_OPTS"].should =~ /--require.*rspec_loader.*--format.*CI::Reporter::RSpecDoc/
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should append to ENV['SPEC_OPTS'] if it already contains a value" do
|
69
|
+
ENV["SPEC_OPTS"] = "somevalue".freeze
|
70
|
+
@rake["ci:setup:rspec"].invoke
|
71
|
+
ENV["SPEC_OPTS"].should =~ /somevalue.*--require.*rspec_loader.*--format.*CI::Reporter::RSpec/
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "ci_reporter ci:setup:cucumber task" do
|
76
|
+
before(:each) do
|
77
|
+
@rake = Rake::Application.new
|
78
|
+
Rake.application = @rake
|
79
|
+
load CI_REPORTER_LIB + '/ci/reporter/rake/cucumber.rb'
|
80
|
+
save_env "CI_REPORTS"
|
81
|
+
save_env "CUCUMBER_OPTS"
|
82
|
+
ENV["CI_REPORTS"] = "some-bogus-nonexistent-directory-that-wont-fail-rm_rf"
|
83
|
+
end
|
84
|
+
after(:each) do
|
85
|
+
restore_env "CUCUMBER_OPTS"
|
86
|
+
restore_env "CI_REPORTS"
|
87
|
+
Rake.application = nil
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should set ENV['CUCUMBER_OPTS'] to include cucumber formatter args" do
|
91
|
+
@rake["ci:setup:cucumber"].invoke
|
92
|
+
ENV["CUCUMBER_OPTS"].should =~ /--require.*cucumber_loader.*--format.*CI::Reporter::Cucumber/
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should append to ENV['CUCUMBER_OPTS'] if it already contains a value" do
|
96
|
+
ENV["CUCUMBER_OPTS"] = "somevalue".freeze
|
97
|
+
@rake["ci:setup:cucumber"].invoke
|
98
|
+
ENV["CUCUMBER_OPTS"].should =~ /somevalue.*--require.*cucumber_loader.*--format.*CI::Reporter::Cucumber/
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright (c) 2006-2010 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + "/../../spec_helper.rb"
|
6
|
+
|
7
|
+
describe "The ReportManager" do
|
8
|
+
before(:each) do
|
9
|
+
@reports_dir = REPORTS_DIR
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:each) do
|
13
|
+
FileUtils.rm_rf @reports_dir
|
14
|
+
ENV["CI_REPORTS"] = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should create the report directory according to the given prefix" do
|
18
|
+
CI::Reporter::ReportManager.new("spec")
|
19
|
+
File.directory?(@reports_dir).should be_true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should create the report directory based on CI_REPORTS environment variable if set" do
|
23
|
+
@reports_dir = "#{Dir.getwd}/dummy"
|
24
|
+
ENV["CI_REPORTS"] = @reports_dir
|
25
|
+
CI::Reporter::ReportManager.new("spec")
|
26
|
+
File.directory?(@reports_dir).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should write reports based on name and xml content of a test suite" do
|
30
|
+
reporter = CI::Reporter::ReportManager.new("spec")
|
31
|
+
suite = mock("test suite")
|
32
|
+
suite.should_receive(:name).and_return("some test suite name")
|
33
|
+
suite.should_receive(:to_xml).and_return("<xml></xml>")
|
34
|
+
reporter.write_report(suite)
|
35
|
+
filename = "#{REPORTS_DIR}/SPEC-some-test-suite-name.xml"
|
36
|
+
File.exist?(filename).should be_true
|
37
|
+
File.open(filename) {|f| f.read.should == "<xml></xml>"}
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should not write files with names longer than 255 characters" do
|
41
|
+
reporter = CI::Reporter::ReportManager.new("spec")
|
42
|
+
suite = mock("test suite")
|
43
|
+
suite.should_receive(:name).and_return("some " + ("long " * 50) + " suite name")
|
44
|
+
suite.should_receive(:to_xml).and_return("<xml></xml>")
|
45
|
+
reporter.write_report(suite)
|
46
|
+
|
47
|
+
files = Dir["#{REPORTS_DIR}/SPEC-some-long-long-long-long*.xml"]
|
48
|
+
files.size.should == 1
|
49
|
+
files.first.split('/').last.size.should <= 255
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# Copyright (c) 2006-2010 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + "/../../spec_helper.rb"
|
6
|
+
require 'stringio'
|
7
|
+
|
8
|
+
describe "The RSpec reporter" do
|
9
|
+
before(:each) do
|
10
|
+
@error = mock("error")
|
11
|
+
@error.stub!(:expectation_not_met?).and_return(false)
|
12
|
+
@error.stub!(:pending_fixed?).and_return(false)
|
13
|
+
@error.stub!(:exception).and_return(StandardError.new)
|
14
|
+
@report_mgr = mock("report manager")
|
15
|
+
@options = mock("options")
|
16
|
+
@args = [@options, StringIO.new("")]
|
17
|
+
@args.shift unless defined?(::Spec) && ::Spec::VERSION::MAJOR == 1 && ::Spec::VERSION::MINOR >= 1
|
18
|
+
@fmt = CI::Reporter::RSpec.new *@args
|
19
|
+
@fmt.report_manager = @report_mgr
|
20
|
+
@formatter = mock("formatter")
|
21
|
+
@fmt.formatter = @formatter
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should use a progress bar formatter by default" do
|
25
|
+
fmt = CI::Reporter::RSpec.new *@args
|
26
|
+
fmt.formatter.should be_instance_of(CI::Reporter::RSpecFormatters::ProgressFormatter)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should use a specdoc formatter for RSpecDoc" do
|
30
|
+
fmt = CI::Reporter::RSpecDoc.new *@args
|
31
|
+
fmt.formatter.should be_instance_of(CI::Reporter::RSpecFormatters::DocFormatter)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should create a test suite with one success, one failure, and one pending" do
|
35
|
+
@report_mgr.should_receive(:write_report).and_return do |suite|
|
36
|
+
suite.testcases.length.should == 3
|
37
|
+
suite.testcases[0].should_not be_failure
|
38
|
+
suite.testcases[0].should_not be_error
|
39
|
+
suite.testcases[1].should be_error
|
40
|
+
suite.testcases[2].name.should =~ /\(PENDING\)/
|
41
|
+
end
|
42
|
+
|
43
|
+
example_group = mock "example group"
|
44
|
+
example_group.stub!(:description).and_return "A context"
|
45
|
+
|
46
|
+
@formatter.should_receive(:start).with(3)
|
47
|
+
@formatter.should_receive(:example_group_started).with(example_group)
|
48
|
+
@formatter.should_receive(:example_started).exactly(3).times
|
49
|
+
@formatter.should_receive(:example_passed).once
|
50
|
+
@formatter.should_receive(:example_failed).once
|
51
|
+
@formatter.should_receive(:example_pending).once
|
52
|
+
@formatter.should_receive(:start_dump).once
|
53
|
+
@formatter.should_receive(:dump_failure).once
|
54
|
+
@formatter.should_receive(:dump_summary).once
|
55
|
+
@formatter.should_receive(:dump_pending).once
|
56
|
+
@formatter.should_receive(:close).once
|
57
|
+
|
58
|
+
@fmt.start(3)
|
59
|
+
@fmt.example_group_started(example_group)
|
60
|
+
@fmt.example_started("should pass")
|
61
|
+
@fmt.example_passed("should pass")
|
62
|
+
@fmt.example_started("should fail")
|
63
|
+
@fmt.example_failed("should fail", 1, @error)
|
64
|
+
@fmt.example_started("should be pending")
|
65
|
+
@fmt.example_pending("A context", "should be pending", "Not Yet Implemented")
|
66
|
+
@fmt.start_dump
|
67
|
+
@fmt.dump_failure(1, mock("failure"))
|
68
|
+
@fmt.dump_summary(0.1, 3, 1, 1)
|
69
|
+
@fmt.dump_pending
|
70
|
+
@fmt.close
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should support RSpec 1.0.8 #add_behavior" do
|
74
|
+
@formatter.should_receive(:start)
|
75
|
+
@formatter.should_receive(:add_behaviour).with("A context")
|
76
|
+
@formatter.should_receive(:example_started).once
|
77
|
+
@formatter.should_receive(:example_passed).once
|
78
|
+
@formatter.should_receive(:dump_summary)
|
79
|
+
@report_mgr.should_receive(:write_report)
|
80
|
+
|
81
|
+
@fmt.start(2)
|
82
|
+
@fmt.add_behaviour("A context")
|
83
|
+
@fmt.example_started("should pass")
|
84
|
+
@fmt.example_passed("should pass")
|
85
|
+
@fmt.dump_summary(0.1, 1, 0, 0)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should use the example #description method when available" do
|
89
|
+
group = mock "example group"
|
90
|
+
group.stub!(:description).and_return "group description"
|
91
|
+
example = mock "example"
|
92
|
+
example.stub!(:description).and_return "should do something"
|
93
|
+
|
94
|
+
@formatter.should_receive(:start)
|
95
|
+
@formatter.should_receive(:example_group_started).with(group)
|
96
|
+
@formatter.should_receive(:example_started).with(example).once
|
97
|
+
@formatter.should_receive(:example_passed).once
|
98
|
+
@formatter.should_receive(:dump_summary)
|
99
|
+
@report_mgr.should_receive(:write_report).and_return do |suite|
|
100
|
+
suite.testcases.last.name.should == "should do something"
|
101
|
+
end
|
102
|
+
|
103
|
+
@fmt.start(2)
|
104
|
+
@fmt.example_group_started(group)
|
105
|
+
@fmt.example_started(example)
|
106
|
+
@fmt.example_passed(example)
|
107
|
+
@fmt.dump_summary(0.1, 1, 0, 0)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should create a test suite with failure in before(:all)" do
|
111
|
+
example_group = mock "example group"
|
112
|
+
example_group.stub!(:description).and_return "A context"
|
113
|
+
|
114
|
+
@formatter.should_receive(:start)
|
115
|
+
@formatter.should_receive(:example_group_started).with(example_group)
|
116
|
+
@formatter.should_receive(:example_started).once
|
117
|
+
@formatter.should_receive(:example_failed).once
|
118
|
+
@formatter.should_receive(:dump_summary)
|
119
|
+
@report_mgr.should_receive(:write_report)
|
120
|
+
|
121
|
+
@fmt.start(2)
|
122
|
+
@fmt.example_group_started(example_group)
|
123
|
+
@fmt.example_failed("should fail", 1, @error)
|
124
|
+
@fmt.dump_summary(0.1, 1, 0, 0)
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'RSpec2Failure' do
|
128
|
+
before(:each) do
|
129
|
+
@rspec20_example = mock('RSpec2.0 Example', :execution_result => {:exception_encountered => StandardError.new('rspec2.0 ftw')})
|
130
|
+
@rspec22_example = mock('RSpec2.2 Example', :execution_result => {:exception => StandardError.new('rspec2.2 ftw')})
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should handle rspec (< 2.2) execution results' do
|
134
|
+
failure = CI::Reporter::RSpec2Failure.new(@rspec20_example)
|
135
|
+
failure.name.should_not be_nil
|
136
|
+
failure.message.should == 'rspec2.0 ftw'
|
137
|
+
failure.location.should_not be_nil
|
138
|
+
end
|
139
|
+
it 'should handle rspec (>= 2.2) execution results' do
|
140
|
+
failure = CI::Reporter::RSpec2Failure.new(@rspec22_example)
|
141
|
+
failure.name.should_not be_nil
|
142
|
+
failure.message.should == 'rspec2.2 ftw'
|
143
|
+
failure.location.should_not be_nil
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# Copyright (c) 2006-2010 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + "/../../spec_helper.rb"
|
6
|
+
require 'rexml/document'
|
7
|
+
|
8
|
+
describe "A TestSuite" do
|
9
|
+
before(:each) do
|
10
|
+
@suite = CI::Reporter::TestSuite.new("example suite")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should collect timings when start and finish are invoked in sequence" do
|
14
|
+
@suite.start
|
15
|
+
@suite.finish
|
16
|
+
@suite.time.should >= 0
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should aggregate tests" do
|
20
|
+
@suite.start
|
21
|
+
@suite.testcases << CI::Reporter::TestCase.new("example test")
|
22
|
+
@suite.finish
|
23
|
+
@suite.tests.should == 1
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should stringify the name for cases when the object passed in is not a string" do
|
27
|
+
name = Object.new
|
28
|
+
def name.to_s; "object name"; end
|
29
|
+
CI::Reporter::TestSuite.new(name).name.should == "object name"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should indicate number of failures and errors" do
|
33
|
+
failure = mock("failure")
|
34
|
+
failure.stub!(:failure?).and_return true
|
35
|
+
failure.stub!(:error?).and_return false
|
36
|
+
|
37
|
+
error = mock("error")
|
38
|
+
error.stub!(:failure?).and_return false
|
39
|
+
error.stub!(:error?).and_return true
|
40
|
+
|
41
|
+
@suite.start
|
42
|
+
@suite.testcases << CI::Reporter::TestCase.new("example test")
|
43
|
+
@suite.testcases << CI::Reporter::TestCase.new("failure test")
|
44
|
+
@suite.testcases.last.failures << failure
|
45
|
+
@suite.testcases << CI::Reporter::TestCase.new("error test")
|
46
|
+
@suite.testcases.last.failures << error
|
47
|
+
@suite.finish
|
48
|
+
@suite.tests.should == 3
|
49
|
+
@suite.failures.should == 1
|
50
|
+
@suite.errors.should == 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "TestSuite xml" do
|
55
|
+
before(:each) do
|
56
|
+
@suite = CI::Reporter::TestSuite.new("example suite")
|
57
|
+
@suite.assertions = 11
|
58
|
+
begin
|
59
|
+
raise StandardError, "an exception occurred"
|
60
|
+
rescue => e
|
61
|
+
@exception = e
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should contain Ant/JUnit-formatted description of entire suite" do
|
66
|
+
failure = mock("failure")
|
67
|
+
failure.stub!(:failure?).and_return true
|
68
|
+
failure.stub!(:error?).and_return false
|
69
|
+
failure.stub!(:name).and_return "failure"
|
70
|
+
failure.stub!(:message).and_return "There was a failure"
|
71
|
+
failure.stub!(:location).and_return @exception.backtrace.join("\n")
|
72
|
+
|
73
|
+
error = mock("error")
|
74
|
+
error.stub!(:failure?).and_return false
|
75
|
+
error.stub!(:error?).and_return true
|
76
|
+
error.stub!(:name).and_return "error"
|
77
|
+
error.stub!(:message).and_return "There was a error"
|
78
|
+
error.stub!(:location).and_return @exception.backtrace.join("\n")
|
79
|
+
|
80
|
+
@suite.start
|
81
|
+
@suite.testcases << CI::Reporter::TestCase.new("example test")
|
82
|
+
@suite.testcases << CI::Reporter::TestCase.new("skipped test").tap {|tc| tc.skipped = true }
|
83
|
+
@suite.testcases << CI::Reporter::TestCase.new("failure test")
|
84
|
+
@suite.testcases.last.failures << failure
|
85
|
+
@suite.testcases << CI::Reporter::TestCase.new("error test")
|
86
|
+
@suite.testcases.last.failures << error
|
87
|
+
@suite.finish
|
88
|
+
|
89
|
+
xml = @suite.to_xml
|
90
|
+
doc = REXML::Document.new(xml)
|
91
|
+
testsuite = doc.root.elements.to_a("/testsuite")
|
92
|
+
testsuite.length.should == 1
|
93
|
+
testsuite = testsuite.first
|
94
|
+
testsuite.attributes["name"].should == "example suite"
|
95
|
+
testsuite.attributes["assertions"].should == "11"
|
96
|
+
|
97
|
+
testcases = testsuite.elements.to_a("testcase")
|
98
|
+
testcases.length.should == 4
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should contain full exception type and message in location element" do
|
102
|
+
failure = mock("failure")
|
103
|
+
failure.stub!(:failure?).and_return true
|
104
|
+
failure.stub!(:error?).and_return false
|
105
|
+
failure.stub!(:name).and_return "failure"
|
106
|
+
failure.stub!(:message).and_return "There was a failure"
|
107
|
+
failure.stub!(:location).and_return @exception.backtrace.join("\n")
|
108
|
+
|
109
|
+
@suite.start
|
110
|
+
@suite.testcases << CI::Reporter::TestCase.new("example test")
|
111
|
+
@suite.testcases << CI::Reporter::TestCase.new("failure test")
|
112
|
+
@suite.testcases.last.failures << failure
|
113
|
+
@suite.finish
|
114
|
+
|
115
|
+
xml = @suite.to_xml
|
116
|
+
doc = REXML::Document.new(xml)
|
117
|
+
elem = doc.root.elements.to_a("/testsuite/testcase[@name='failure test']/failure").first
|
118
|
+
location = elem.texts.join
|
119
|
+
location.should =~ Regexp.new(failure.message)
|
120
|
+
location.should =~ Regexp.new(failure.name)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should filter attributes properly for invalid characters" do
|
124
|
+
failure = mock("failure")
|
125
|
+
failure.stub!(:failure?).and_return true
|
126
|
+
failure.stub!(:error?).and_return false
|
127
|
+
failure.stub!(:name).and_return "failure"
|
128
|
+
failure.stub!(:message).and_return "There was a <failure>\nReason: blah"
|
129
|
+
failure.stub!(:location).and_return @exception.backtrace.join("\n")
|
130
|
+
|
131
|
+
@suite.start
|
132
|
+
@suite.testcases << CI::Reporter::TestCase.new("failure test")
|
133
|
+
@suite.testcases.last.failures << failure
|
134
|
+
@suite.finish
|
135
|
+
|
136
|
+
xml = @suite.to_xml
|
137
|
+
xml.should =~ %r/message="There was a <failure>\.\.\."/
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "A TestCase" do
|
142
|
+
before(:each) do
|
143
|
+
@tc = CI::Reporter::TestCase.new("example test")
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should collect timings when start and finish are invoked in sequence" do
|
147
|
+
@tc.start
|
148
|
+
@tc.finish
|
149
|
+
@tc.time.should >= 0
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# Copyright (c) 2006-2010 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + "/../../spec_helper.rb"
|
6
|
+
|
7
|
+
describe "The TestUnit reporter" do
|
8
|
+
before(:each) do
|
9
|
+
@report_mgr = mock("report manager")
|
10
|
+
@testunit = CI::Reporter::TestUnit.new(nil, @report_mgr)
|
11
|
+
@result = mock("result")
|
12
|
+
@result.stub!(:assertion_count).and_return(7)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should build suites based on adjacent tests with the same class name" do
|
16
|
+
@suite = nil
|
17
|
+
@report_mgr.should_receive(:write_report).once.and_return {|suite| @suite = suite }
|
18
|
+
|
19
|
+
@testunit.started(@result)
|
20
|
+
@testunit.test_started("test_one(TestCaseClass)")
|
21
|
+
@testunit.test_finished("test_one(TestCaseClass)")
|
22
|
+
@testunit.test_started("test_two(TestCaseClass)")
|
23
|
+
@testunit.test_finished("test_two(TestCaseClass)")
|
24
|
+
@testunit.finished(10)
|
25
|
+
|
26
|
+
@suite.name.should == "TestCaseClass"
|
27
|
+
@suite.testcases.length.should == 2
|
28
|
+
@suite.testcases.first.name.should == "test_one"
|
29
|
+
@suite.testcases.first.should_not be_failure
|
30
|
+
@suite.testcases.first.should_not be_error
|
31
|
+
@suite.testcases.last.name.should == "test_two"
|
32
|
+
@suite.testcases.last.should_not be_failure
|
33
|
+
@suite.testcases.last.should_not be_error
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should build two suites when encountering different class names" do
|
37
|
+
@suites = []
|
38
|
+
@report_mgr.should_receive(:write_report).twice.and_return {|suite| @suites << suite }
|
39
|
+
|
40
|
+
@testunit.started(@result)
|
41
|
+
@testunit.test_started("test_one(TestCaseClass)")
|
42
|
+
@testunit.test_finished("test_one(TestCaseClass)")
|
43
|
+
@testunit.test_started("test_two(AnotherTestCaseClass)")
|
44
|
+
@testunit.test_finished("test_two(AnotherTestCaseClass)")
|
45
|
+
@testunit.finished(10)
|
46
|
+
|
47
|
+
@suites.first.name.should == "TestCaseClass"
|
48
|
+
@suites.first.testcases.length.should == 1
|
49
|
+
@suites.first.testcases.first.name.should == "test_one"
|
50
|
+
@suites.first.testcases.first.assertions.should == 7
|
51
|
+
|
52
|
+
@suites.last.name.should == "AnotherTestCaseClass"
|
53
|
+
@suites.last.testcases.length.should == 1
|
54
|
+
@suites.last.testcases.first.name.should == "test_two"
|
55
|
+
@suites.last.testcases.first.assertions.should == 0
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should record assertion counts during test run" do
|
59
|
+
@suite = nil
|
60
|
+
@report_mgr.should_receive(:write_report).and_return {|suite| @suite = suite }
|
61
|
+
|
62
|
+
@testunit.started(@result)
|
63
|
+
@testunit.test_started("test_one(TestCaseClass)")
|
64
|
+
@testunit.test_finished("test_one(TestCaseClass)")
|
65
|
+
@testunit.finished(10)
|
66
|
+
|
67
|
+
@suite.assertions.should == 7
|
68
|
+
@suite.testcases.last.assertions.should == 7
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should add failures to testcases when encountering a fault" do
|
72
|
+
@failure = Test::Unit::Failure.new("test_one(TestCaseClass)", "somewhere:10", "it failed")
|
73
|
+
|
74
|
+
@suite = nil
|
75
|
+
@report_mgr.should_receive(:write_report).once.and_return {|suite| @suite = suite }
|
76
|
+
|
77
|
+
@testunit.started(@result)
|
78
|
+
@testunit.test_started("test_one(TestCaseClass)")
|
79
|
+
@testunit.fault(@failure)
|
80
|
+
@testunit.test_finished("test_one(TestCaseClass)")
|
81
|
+
@testunit.finished(10)
|
82
|
+
|
83
|
+
@suite.name.should == "TestCaseClass"
|
84
|
+
@suite.testcases.length.should == 1
|
85
|
+
@suite.testcases.first.name.should == "test_one"
|
86
|
+
@suite.testcases.first.should be_failure
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should add errors to testcases when encountering a fault" do
|
90
|
+
begin
|
91
|
+
raise StandardError, "error"
|
92
|
+
rescue => e
|
93
|
+
@error = Test::Unit::Error.new("test_two(TestCaseClass)", e)
|
94
|
+
end
|
95
|
+
|
96
|
+
@suite = nil
|
97
|
+
@report_mgr.should_receive(:write_report).once.and_return {|suite| @suite = suite }
|
98
|
+
|
99
|
+
@testunit.started(@result)
|
100
|
+
@testunit.test_started("test_one(TestCaseClass)")
|
101
|
+
@testunit.test_finished("test_one(TestCaseClass)")
|
102
|
+
@testunit.test_started("test_two(TestCaseClass)")
|
103
|
+
@testunit.fault(@error)
|
104
|
+
@testunit.test_finished("test_two(TestCaseClass)")
|
105
|
+
@testunit.finished(10)
|
106
|
+
|
107
|
+
@suite.name.should == "TestCaseClass"
|
108
|
+
@suite.testcases.length.should == 2
|
109
|
+
@suite.testcases.first.name.should == "test_one"
|
110
|
+
@suite.testcases.first.should_not be_failure
|
111
|
+
@suite.testcases.first.should_not be_error
|
112
|
+
@suite.testcases.last.name.should == "test_two"
|
113
|
+
@suite.testcases.last.should_not be_failure
|
114
|
+
@suite.testcases.last.should be_error
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should add multiple failures to a testcase" do
|
118
|
+
@failure1 = Test::Unit::Failure.new("test_one(TestCaseClass)", "somewhere:10", "it failed")
|
119
|
+
@failure2 = Test::Unit::Failure.new("test_one(TestCaseClass)", "somewhere:12", "it failed again in teardown")
|
120
|
+
|
121
|
+
@suite = nil
|
122
|
+
@report_mgr.should_receive(:write_report).once.and_return {|suite| @suite = suite }
|
123
|
+
|
124
|
+
@testunit.started(@result)
|
125
|
+
@testunit.test_started("test_one(TestCaseClass)")
|
126
|
+
@testunit.fault(@failure1)
|
127
|
+
@testunit.fault(@failure2)
|
128
|
+
@testunit.test_finished("test_one(TestCaseClass)")
|
129
|
+
@testunit.finished(10)
|
130
|
+
|
131
|
+
@suite.name.should == "TestCaseClass"
|
132
|
+
@suite.testcases.length.should == 1
|
133
|
+
@suite.testcases.first.name.should == "test_one"
|
134
|
+
@suite.testcases.first.should be_failure
|
135
|
+
@suite.testcases.first.failures.size.should == 2
|
136
|
+
@suite.failures.should == 2
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should count test case names that don't conform to the standard pattern" do
|
140
|
+
@suite = nil
|
141
|
+
@report_mgr.should_receive(:write_report).once.and_return {|suite| @suite = suite }
|
142
|
+
|
143
|
+
@testunit.started(@result)
|
144
|
+
@testunit.test_started("some unknown test")
|
145
|
+
@testunit.test_finished("some unknown test")
|
146
|
+
@testunit.finished(10)
|
147
|
+
|
148
|
+
@suite.name.should == "unknown-1"
|
149
|
+
@suite.testcases.length.should == 1
|
150
|
+
@suite.testcases.first.name.should == "some unknown test"
|
151
|
+
end
|
152
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright (c) 2006-2010 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
# See the file LICENSE.txt included with the distribution for
|
3
|
+
# software license details.
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
begin
|
7
|
+
require 'rspec'
|
8
|
+
rescue LoadError
|
9
|
+
require 'spec'
|
10
|
+
end
|
11
|
+
|
12
|
+
unless defined?(CI_REPORTER_LIB)
|
13
|
+
CI_REPORTER_LIB = File.expand_path(File.dirname(__FILE__) + "/../lib")
|
14
|
+
$: << CI_REPORTER_LIB
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'ci/reporter/core'
|
18
|
+
require 'ci/reporter/test_unit'
|
19
|
+
require 'ci/reporter/rspec'
|
20
|
+
|
21
|
+
REPORTS_DIR = File.dirname(__FILE__) + "/reports" unless defined?(REPORTS_DIR)
|