ci_reporter 1.5.3 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ == 1.6.0
2
+
3
+ - Add support for Cucumber (tested against 0.3.0 - 0.3.2); (Graeme Mathieson)
4
+
1
5
  == 1.5.3
2
6
 
3
7
  - Compatibility with latest RSpec (1.2.4); (Paul Boone)
data/Manifest.txt CHANGED
@@ -5,6 +5,9 @@ LICENSE.txt
5
5
  Rakefile
6
6
  stub.rake
7
7
  lib/ci/reporter/core.rb
8
+ lib/ci/reporter/cucumber.rb
9
+ lib/ci/reporter/rake/cucumber.rb
10
+ lib/ci/reporter/rake/cucumber_loader.rb
8
11
  lib/ci/reporter/rake/rspec.rb
9
12
  lib/ci/reporter/rake/rspec_loader.rb
10
13
  lib/ci/reporter/rake/test_unit.rb
@@ -14,6 +17,7 @@ lib/ci/reporter/rspec.rb
14
17
  lib/ci/reporter/test_suite.rb
15
18
  lib/ci/reporter/test_unit.rb
16
19
  lib/ci/reporter/version.rb
20
+ spec/ci/reporter/cucumber_spec.rb
17
21
  spec/ci/reporter/output_capture_spec.rb
18
22
  spec/ci/reporter/rake/rake_tasks_spec.rb
19
23
  spec/ci/reporter/report_manager_spec.rb
data/README.txt CHANGED
@@ -1,4 +1,4 @@
1
- CI::Reporter is an add-on to Test::Unit and RSpec that allows you to generate XML reports of your test and/or spec runs. The resulting files can be read by a continuous integration system that understands Ant's JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.
1
+ CI::Reporter is an add-on to Test::Unit, RSpec and Cucumber that allows you to generate XML reports of your test, spec and/or feature runs. The resulting files can be read by a continuous integration system that understands Ant's JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.
2
2
 
3
3
  == Dependencies
4
4
 
@@ -22,14 +22,15 @@ CI::Reporter works best with projects that use a +Rakefile+ along with the stand
22
22
 
23
23
  require 'rubygems'
24
24
  gem 'ci_reporter'
25
- require 'ci/reporter/rake/rspec' # use this if you're using RSpec
25
+ require 'ci/reporter/rake/rspec' # use this if you're using RSpec
26
+ require 'ci/reporter/rake/cucumber' # use this if you're using Cucumber
26
27
  require 'ci/reporter/rake/test_unit' # use this if you're using Test::Unit
27
28
 
28
- 2. Next, either modify your Rakefile to make the <code>ci:setup:rspec</code> or <code>ci:setup:testunit</code> task a dependency of your test tasks, or include them on the Rake command-line before the name of the task that runs the tests or specs.
29
+ 2. Next, either modify your Rakefile to make the <code>ci:setup:rspec</code>, <code>ci:setup:cucumber</code> or <code>ci:setup:testunit</code> task a dependency of your test tasks, or include them on the Rake command-line before the name of the task that runs the tests or specs.
29
30
 
30
31
  rake ci:setup:testunit test
31
32
 
32
- Report files are written, by default, to the <code>test/reports</code> or <code>spec/reports</code> subdirectory of your project. If you wish to customize the location, simply set the environment variable CI_REPORTS (either in the environment, on the Rake command line, or in your Rakefile) to the location where they should go.
33
+ Report files are written, by default, to the <code>test/reports</code>, <code>features/reports</code> or <code>spec/reports</code> subdirectory of your project. If you wish to customize the location, simply set the environment variable CI_REPORTS (either in the environment, on the Rake command line, or in your Rakefile) to the location where they should go.
33
34
 
34
35
  == Advanced Usage
35
36
 
@@ -37,14 +38,21 @@ If you don't have control over the Rakefile or don't want to modify it, CI::Repo
37
38
 
38
39
  rake -f GEM_PATH/stub.rake ci:setup:testunit test
39
40
  rake -f GEM_PATH/stub.rake ci:setup:rspec spec
41
+ rake -f GEM_PATH/stub.rake ci:setup:cucumber features
40
42
 
41
43
  If for some reason you can't use the above technique to inject CI::Reporter (e.g., you're not using Rake), you'll have to do one of these:
42
44
 
43
45
  1. If you're using <code>Test::Unit</code>, ensure the <code>ci/reporter/rake/test_unit_loader.rb</code> file is loaded or required at some point before the tests are run.
46
+
44
47
  2. If you're using +RSpec+, you'll need to pass the following arguments to the +spec+ command:
48
+
45
49
  --require GEM_PATH/lib/ci/reporter/rake/rspec_loader
46
50
  --format CI::Reporter::RSpec
47
51
 
52
+ 3. If you're using Cucumber, you'll need to cheat slightly so that Cucumber's step definition autoloading will still work. Instead of calling the +cucumber+ script directly, run:
53
+
54
+ ruby -r GEM_PATH/lib/ci/reporter/rake/cucumber_loader -S cucumber --format CI::Reporter::Cucumber
55
+
48
56
  There's a bit of a chicken and egg problem because rubygems needs to be loaded before you can require any CI::Reporter files. If you cringe hard-coding a full path to a specific version of the gem, you can also copy the +rspec_loader+ file into your project and require it directly -- the contents are version-agnostic and are not likely to change in future releases.
49
57
 
50
58
  == Environment Variables
data/Rakefile CHANGED
@@ -58,11 +58,12 @@ end
58
58
  task :rcov => "spec:rcov"
59
59
 
60
60
  task :generate_output do
61
- rm_f "acceptance/reports/*.xml"
61
+ rm_rf "acceptance/reports"
62
62
  ENV['CI_REPORTS'] = "acceptance/reports"
63
63
  begin
64
64
  `ruby -Ilib acceptance/test_unit_example_test.rb` rescue nil
65
65
  `ruby -Ilib -S spec --require ci/reporter/rake/rspec_loader --format CI::Reporter::RSpec acceptance/rspec_example_spec.rb` rescue nil
66
+ `ruby -Ilib -rci/reporter/rake/cucumber_loader -S cucumber --format CI::Reporter::Cucumber acceptance/cucumber` rescue nil
66
67
  ensure
67
68
  ENV.delete 'CI_REPORTS'
68
69
  end
@@ -0,0 +1,99 @@
1
+ # (c) Copyright 2006-2009 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
+ tried_gem = false
7
+ begin
8
+ require 'cucumber'
9
+ require 'cucumber/ast/visitor'
10
+ rescue LoadError
11
+ unless tried_gem
12
+ tried_gem = true
13
+ require 'rubygems'
14
+ gem 'cucumber'
15
+ retry
16
+ end
17
+ end
18
+
19
+ module CI
20
+ module Reporter
21
+ class CucumberFailure
22
+ attr_reader :step
23
+
24
+ def initialize(step)
25
+ @step = step
26
+ end
27
+
28
+ def failure?
29
+ true
30
+ end
31
+
32
+ def error?
33
+ !failure?
34
+ end
35
+
36
+ def name
37
+ step.exception.class.name
38
+ end
39
+
40
+ def message
41
+ step.exception.message
42
+ end
43
+
44
+ def location
45
+ step.exception.backtrace.join("\n")
46
+ end
47
+ end
48
+
49
+ class Cucumber < ::Cucumber::Ast::Visitor
50
+
51
+ attr_accessor :test_suite, :report_manager, :feature_name
52
+
53
+ def initialize(step_mother, io, options)
54
+ self.report_manager = ReportManager.new("features")
55
+ super(step_mother)
56
+ end
57
+
58
+ def visit_feature_name(name)
59
+ self.feature_name = name.split("\n").first
60
+ super
61
+ end
62
+
63
+ def visit_feature_element(feature_element)
64
+ self.test_suite = TestSuite.new("#{feature_name} #{feature_element.instance_variable_get("@name")}")
65
+ test_suite.start
66
+
67
+ return_value = super
68
+
69
+ test_suite.finish
70
+ report_manager.write_report(test_suite)
71
+ self.test_suite = nil
72
+
73
+ return_value
74
+ end
75
+
76
+ def visit_step(step)
77
+ test_case = TestCase.new(step.name)
78
+ test_case.start
79
+
80
+ return_value = super
81
+
82
+ test_case.finish
83
+
84
+ case step.status
85
+ when :pending, :undefined
86
+ test_case.name = "#{test_case.name} (PENDING)"
87
+ when :skipped
88
+ test_case.name = "#{test_case.name} (SKIPPED)"
89
+ when :failed
90
+ test_case.failures << CucumberFailure.new(step)
91
+ end
92
+
93
+ test_suite.testcases << test_case
94
+
95
+ return_value
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,17 @@
1
+ # (c) Copyright 2006-2007 Nick Sieger <nicksieger@gmail.com>
2
+ # See the file LICENSE.txt included with the distribution for
3
+ # software license details.
4
+
5
+ namespace :ci do
6
+ namespace :setup do
7
+ task :cucumber_report_cleanup do
8
+ rm_rf ENV["CI_REPORTS"] || "features/reports"
9
+ end
10
+
11
+ task :cucumber => :cucumber_report_cleanup do
12
+ spec_opts = ["--require", "#{File.dirname(__FILE__)}/cucumber_loader.rb",
13
+ "--format", "CI::Reporter::Cucumber"].join(" ")
14
+ ENV["CUCUMBER_OPTS"] = "#{ENV['CUCUMBER_OPTS']} #{spec_opts}"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ # (c) Copyright 2006-2007 Nick Sieger <nicksieger@gmail.com>
2
+ # See the file LICENSE.txt included with the distribution for
3
+ # software license details.
4
+
5
+ $: << File.dirname(__FILE__) + "/../../.."
6
+ require 'ci/reporter/cucumber'
@@ -1,5 +1,5 @@
1
1
  module CI
2
2
  module Reporter
3
- VERSION = "1.5.3"
3
+ VERSION = "1.6.0"
4
4
  end
5
5
  end
@@ -0,0 +1,204 @@
1
+ # (c) Copyright 2006-2008 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 'ci/reporter/cucumber'
7
+
8
+ describe "The Cucumber reporter" do
9
+ describe CI::Reporter::CucumberFailure do
10
+ before(:each) do
11
+ @klass = mock("class")
12
+ @klass.stub!(:name).and_return("Exception name")
13
+
14
+ @exception = mock("exception")
15
+ @exception.stub!(:class).and_return(@klass)
16
+ @exception.stub!(:message).and_return("Exception message")
17
+ @exception.stub!(:backtrace).and_return(["First line", "Second line"])
18
+
19
+ @step = mock("step")
20
+ @step.stub!(:exception).and_return(@exception)
21
+
22
+ @cucumber_failure = CI::Reporter::CucumberFailure.new(@step)
23
+ end
24
+
25
+ it "should always return true for failure?" do
26
+ @cucumber_failure.should be_failure
27
+ end
28
+
29
+ it "should always return false for error?" do
30
+ @cucumber_failure.should_not be_error
31
+ end
32
+
33
+ it "should propagate the name as the underlying exception's class name" do
34
+ @step.should_receive(:exception)
35
+ @exception.should_receive(:class)
36
+ @klass.should_receive(:name)
37
+
38
+ @cucumber_failure.name.should == "Exception name"
39
+ end
40
+
41
+ it "should propagate the message as the underlying exception's message" do
42
+ @step.should_receive(:exception)
43
+ @exception.should_receive(:message)
44
+
45
+ @cucumber_failure.message.should == "Exception message"
46
+ end
47
+
48
+ it "should propagate and format the exception's backtrace" do
49
+ @step.should_receive(:exception)
50
+ @exception.should_receive(:backtrace)
51
+
52
+ @cucumber_failure.location.should == "First line\nSecond line"
53
+ end
54
+ end
55
+
56
+ describe CI::Reporter::Cucumber do
57
+ before(:each) do
58
+ @step_mother = mock("step_mother")
59
+ @io = mock("io")
60
+
61
+ @report_manager = mock("report_manager")
62
+ CI::Reporter::ReportManager.stub!(:new).and_return(@report_manager)
63
+ end
64
+
65
+ def new_instance
66
+ CI::Reporter::Cucumber.new(@step_mother, @io, {})
67
+ end
68
+
69
+ it "should create a new report manager to report on test success/failure" do
70
+ CI::Reporter::ReportManager.should_receive(:new)
71
+ new_instance
72
+ end
73
+
74
+ it "should record the feature name when a new feature is visited" do
75
+ cucumber = new_instance
76
+ cucumber.visit_feature_name("Some feature name")
77
+ cucumber.feature_name.should == "Some feature name"
78
+ end
79
+
80
+ it "should record only the first line of a feature name" do
81
+ cucumber = new_instance
82
+ cucumber.visit_feature_name("Some feature name\nLonger description")
83
+ cucumber.feature_name.should == "Some feature name"
84
+ end
85
+
86
+ describe "when visiting a new scenario" do
87
+ before(:each) do
88
+ @cucumber = new_instance
89
+ @cucumber.visit_feature_name("Demo feature")
90
+
91
+ @test_suite = mock("test_suite", :start => nil, :finish => nil)
92
+ CI::Reporter::TestSuite.stub!(:new).and_return(@test_suite)
93
+
94
+ @feature_element = mock("feature_element", :accept => true)
95
+
96
+ @report_manager.stub!(:write_report)
97
+ end
98
+
99
+ it "should create a new test suite" do
100
+ # FIXME: @name is feature_element purely as a by-product of the
101
+ # mocking framework implementation. But then again, using
102
+ # +instance_variable_get+ in the first place is a bit icky.
103
+ CI::Reporter::TestSuite.should_receive(:new).with("Demo feature feature_element")
104
+ @cucumber.visit_feature_element(@feature_element)
105
+ end
106
+
107
+ it "should indicate that the test suite has started" do
108
+ @test_suite.should_receive(:start)
109
+ @cucumber.visit_feature_element(@feature_element)
110
+ end
111
+
112
+ it "should indicate that the test suite has finished" do
113
+ @test_suite.should_receive(:finish)
114
+ @cucumber.visit_feature_element(@feature_element)
115
+ end
116
+
117
+ it "should ask the report manager to write a report" do
118
+ @report_manager.should_receive(:write_report).with(@test_suite)
119
+ @cucumber.visit_feature_element(@feature_element)
120
+ end
121
+ end
122
+
123
+ describe "when visiting a step inside a scenario" do
124
+ before(:each) do
125
+ @testcases = []
126
+
127
+ @test_suite = mock("test_suite", :testcases => @testcases)
128
+
129
+ @cucumber = new_instance
130
+ @cucumber.stub!(:test_suite).and_return(@test_suite)
131
+
132
+ @test_case = mock("test_case", :start => nil, :finish => nil, :name => "Step Name")
133
+ CI::Reporter::TestCase.stub!(:new).and_return(@test_case)
134
+
135
+ @step = mock("step", :accept => true, :status => :passed)
136
+ @step.stub!(:name).and_return("Step Name")
137
+ end
138
+
139
+ it "should create a new test case" do
140
+ CI::Reporter::TestCase.should_receive(:new).with("Step Name")
141
+ @cucumber.visit_step(@step)
142
+ end
143
+
144
+ it "should indicate that the test case has started" do
145
+ @test_case.should_receive(:start)
146
+ @cucumber.visit_step(@step)
147
+ end
148
+
149
+ it "should indicate that the test case has finished" do
150
+ @test_case.should_receive(:finish)
151
+ @cucumber.visit_step(@step)
152
+ end
153
+
154
+ it "should add the test case to the suite's list of cases" do
155
+ @testcases.should be_empty
156
+ @cucumber.visit_step(@step)
157
+ @testcases.should_not be_empty
158
+ @testcases.first.should == @test_case
159
+ end
160
+
161
+ it "should alter the name of a test case that is pending to include '(PENDING)'" do
162
+ @step.stub!(:status).and_return(:pending)
163
+ @test_case.should_receive(:name=).with("Step Name (PENDING)")
164
+ @cucumber.visit_step(@step)
165
+ end
166
+
167
+ it "should alter the name of a test case that is undefined to include '(PENDING)'" do
168
+ @step.stub!(:status).and_return(:undefined)
169
+ @test_case.should_receive(:name=).with("Step Name (PENDING)")
170
+ @cucumber.visit_step(@step)
171
+ end
172
+
173
+ it "should alter the name of a test case that was skipped to include '(SKIPPED)'" do
174
+ @step.stub!(:status).and_return(:skipped)
175
+ @test_case.should_receive(:name=).with("Step Name (SKIPPED)")
176
+ @cucumber.visit_step(@step)
177
+ end
178
+
179
+ describe "that fails" do
180
+ before(:each) do
181
+ @step.stub!(:status).and_return(:failed)
182
+
183
+ @failures = []
184
+ @test_case.stub!(:failures).and_return(@failures)
185
+
186
+ @cucumber_failure = mock("cucumber_failure")
187
+ CI::Reporter::CucumberFailure.stub!(:new).and_return(@cucumber_failure)
188
+ end
189
+
190
+ it "should create a new cucumber failure with that step" do
191
+ CI::Reporter::CucumberFailure.should_receive(:new).with(@step)
192
+ @cucumber.visit_step(@step)
193
+ end
194
+
195
+ it "should add the failure to the suite's list of failures" do
196
+ @failures.should be_empty
197
+ @cucumber.visit_step(@step)
198
+ @failures.should_not be_empty
199
+ @failures.first.should == @cucumber_failure
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
@@ -71,3 +71,30 @@ describe "ci_reporter ci:setup:rspec task" do
71
71
  ENV["SPEC_OPTS"].should =~ /somevalue.*--require.*rspec_loader.*--format.*CI::Reporter::RSpec/
72
72
  end
73
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
data/stub.rake CHANGED
@@ -9,5 +9,6 @@
9
9
  #
10
10
 
11
11
  load File.dirname(__FILE__) + '/lib/ci/reporter/rake/rspec.rb'
12
+ load File.dirname(__FILE__) + '/lib/ci/reporter/rake/cucumber.rb'
12
13
  load File.dirname(__FILE__) + '/lib/ci/reporter/rake/test_unit.rb'
13
14
  load 'Rakefile'
@@ -4,13 +4,15 @@
4
4
 
5
5
  begin
6
6
  gem 'ci_reporter'
7
- rescue
7
+ rescue Gem::LoadError
8
8
  $: << File.dirname(__FILE__) + "/../lib"
9
9
  end
10
10
  require 'ci/reporter/rake/rspec'
11
+ require 'ci/reporter/rake/cucumber'
11
12
  require 'ci/reporter/rake/test_unit'
12
13
 
13
14
  namespace :ci do
14
15
  task :setup_rspec => "ci:setup:rspec"
16
+ task :setup_cucumber => "ci:setup:cucumber"
15
17
  task :setup_testunit => "ci:setup:testunit"
16
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ci_reporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sieger
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-18 00:00:00 -05:00
12
+ date: 2009-05-05 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,7 +22,7 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 2.1.2
24
24
  version:
25
- description: CI::Reporter is an add-on to Test::Unit and RSpec that allows you to generate XML reports of your test and/or spec runs. The resulting files can be read by a continuous integration system that understands Ant's JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.
25
+ description: CI::Reporter is an add-on to Test::Unit, RSpec and Cucumber that allows you to generate XML reports of your test, spec and/or feature runs. The resulting files can be read by a continuous integration system that understands Ant's JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.
26
26
  email: nick@nicksieger.com
27
27
  executables: []
28
28
 
@@ -41,6 +41,9 @@ files:
41
41
  - Rakefile
42
42
  - stub.rake
43
43
  - lib/ci/reporter/core.rb
44
+ - lib/ci/reporter/cucumber.rb
45
+ - lib/ci/reporter/rake/cucumber.rb
46
+ - lib/ci/reporter/rake/cucumber_loader.rb
44
47
  - lib/ci/reporter/rake/rspec.rb
45
48
  - lib/ci/reporter/rake/rspec_loader.rb
46
49
  - lib/ci/reporter/rake/test_unit.rb
@@ -50,6 +53,7 @@ files:
50
53
  - lib/ci/reporter/test_suite.rb
51
54
  - lib/ci/reporter/test_unit.rb
52
55
  - lib/ci/reporter/version.rb
56
+ - spec/ci/reporter/cucumber_spec.rb
53
57
  - spec/ci/reporter/output_capture_spec.rb
54
58
  - spec/ci/reporter/rake/rake_tasks_spec.rb
55
59
  - spec/ci/reporter/report_manager_spec.rb
@@ -86,6 +90,7 @@ signing_key:
86
90
  specification_version: 2
87
91
  summary: CI::Reporter allows you to generate reams of XML for use with continuous integration systems.
88
92
  test_files:
93
+ - spec/ci/reporter/cucumber_spec.rb
89
94
  - spec/ci/reporter/output_capture_spec.rb
90
95
  - spec/ci/reporter/rake/rake_tasks_spec.rb
91
96
  - spec/ci/reporter/report_manager_spec.rb