yarjuf 1.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.
Files changed (5) hide show
  1. data/HISTORY.txt +3 -0
  2. data/LICENSE.txt +29 -0
  3. data/README.md +102 -0
  4. data/lib/yarjuf.rb +80 -0
  5. metadata +65 -0
@@ -0,0 +1,3 @@
1
+ 1.0
2
+ - Initial release
3
+
@@ -0,0 +1,29 @@
1
+ Copyright (c) 2012, Nathaniel Ritmeyer
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name Nathaniel Ritmeyer nor the names of contributors to
15
+ this software may be used to endorse or promote products derived from this
16
+ software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
19
+ IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
22
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
@@ -0,0 +1,102 @@
1
+ # yarjuf
2
+
3
+ _Yet Another RSpec JUnit Formatter_
4
+
5
+ ## Intro
6
+
7
+ I've never found a gem that can be relied on to generate JUnit
8
+ output from [RSpec](https://www.relishapp.com/rspec/rspec-core/docs). Previously, I'd cobbled together a [formatter](http://www.natontesting.com/2012/05/25/rspec-junit-formatter-for-jenkins/) that worked for me for a couple of years and seems to have proved
9
+ useful to others. But it was a hack and thought I'd rewrite it, make it
10
+ conform to the JUnit format spec a bit better, and make it
11
+ distributable as a gem. Thus: [yet-another-rspec-junit-formatter](https://github.com/natritmeyer/yarjuf)
12
+
13
+ ## Installation
14
+
15
+ Using rubygems:
16
+
17
+ `gem install yarjuf`
18
+
19
+ Using bundler:
20
+
21
+ Add the following line to your `Gemfile`:
22
+
23
+ `gem 'yarjuf'`
24
+
25
+ ## Usage
26
+
27
+ There are a few ways to use custom formatters in RSpec; what follows is
28
+ the 'best' way...
29
+
30
+ ### Loading yarjuf
31
+
32
+ Before you can use yarjuf, RSpec needs to know about it. The best way to
33
+ do that is to use the functionality that RSpec provides to load
34
+ libraries.
35
+
36
+ #### Modifying the `.rspec` file
37
+
38
+ When RSpec executes, it looks for a file in the current working
39
+ directory (project root) called `.rspec` that contains rspec
40
+ configuration. It is a good idea to add the following to it:
41
+
42
+ `--require spec_helper`
43
+
44
+ Doing so will make sure that the `spec/spec_helper.rb` file will get
45
+ required when RSpec starts.
46
+
47
+ #### Modifying the `spec/spec_helper.rb` file
48
+
49
+ Add the following to your `spec/spec_helper.rb`:
50
+
51
+ ```ruby
52
+ require 'yarjuf'
53
+ ```
54
+
55
+ That will make sure that yarjuf is loaded when RSpec starts and can be
56
+ used as a formatter.
57
+
58
+ ### Generating JUnit output using yarjuf
59
+
60
+ RSpec tests can be executed in a number of ways. Here's how to get JUnit
61
+ output for each of those different ways - assuming you've loaded yarjuf
62
+ as specified above).
63
+
64
+ #### Running rspec tests from the command line
65
+
66
+ In this scenario, you just want to run `rspec` from the command line and
67
+ get JUnit output. To do that you'll need to use the `-f JUnit` option
68
+ to generate JUnit output and to write it to a file you can use the
69
+ `-o results.xml` option. So to run all your tests and get JUnit output
70
+ written to a file, execute the following:
71
+
72
+ `rspec -f JUnit -o results.xml`
73
+
74
+ #### Running rspec tests using Rake
75
+
76
+ In this scenario, you want to run your rspec tests using rake. To do
77
+ that you'll need to add an option to your rake task:
78
+
79
+ ```ruby
80
+ RSpec::Core::RakeTask.new(:spec) do |t|
81
+ t.rspec_opts = %w[-f JUnit -o results.xml]
82
+ end
83
+ ```
84
+
85
+ That will write out JUnit formatted results to a file called
86
+ `results.xml`.
87
+
88
+ #### Jenkins integration
89
+
90
+ To use yarjuf with Jenkins(/Hudson), simply tick the 'Publish JUnit test
91
+ result report' option in the Jenkins task configuration page and in the
92
+ 'Test report XMLs' field specify the file name that you expect the JUnit
93
+ formatted results to be written to, ie: the file path and name specified
94
+ in the `-o` option above.
95
+
96
+ ## Acknowledgements
97
+
98
+ * Thanks to [@adeoke](https://github.com/adeoke) for suggesting a slightly less sucky gem name than the
99
+ one I originally came up with
100
+ * Thanks to [@dchamb84](https://github.com/dchamb84) for helping me debug the original hack
101
+ * Thanks to [@nathanbain](https://github.com/nathanbain) for spurring me on to write the original hack
102
+
@@ -0,0 +1,80 @@
1
+ require 'time'
2
+ require 'builder'
3
+ require 'rspec/core/formatters/base_formatter'
4
+
5
+ class JUnit < RSpec::Core::Formatters::BaseFormatter
6
+ def initialize(output)
7
+ super output
8
+ @test_suite_results = {}
9
+ end
10
+
11
+ def example_passed(example)
12
+ add_to_test_suite_results(example)
13
+ end
14
+
15
+ def example_failed(example)
16
+ add_to_test_suite_results(example)
17
+ end
18
+
19
+ def example_pending(example)
20
+ add_to_test_suite_results(example)
21
+ end
22
+
23
+ def add_to_test_suite_results(example)
24
+ suite_name = root_group_name_for(example)
25
+ @test_suite_results[suite_name] = [] unless @test_suite_results.keys.include?(suite_name)
26
+ @test_suite_results[suite_name] << example
27
+ end
28
+
29
+ def root_group_name_for(example)
30
+ group_hierarchy_for(example).first[:description]
31
+ end
32
+
33
+ def group_hierarchy_for(example)
34
+ group_hierarchy = []
35
+ current_example_group = example.metadata[:example_group]
36
+ until current_example_group.nil? do
37
+ group_hierarchy.unshift current_example_group
38
+ current_example_group = current_example_group[:example_group]
39
+ end
40
+ group_hierarchy
41
+ end
42
+
43
+ def failure_details_for(example)
44
+ exception = example.metadata[:execution_result][:exception]
45
+ exception.nil? ? "" : "#{exception.message}\n#{format_backtrace(exception.backtrace, example).join("\n")}"
46
+ end
47
+
48
+ def fail_count_for_suite(suite)
49
+ suite.select {|example| example.metadata[:execution_result][:status] == "failed"}.size
50
+ end
51
+
52
+ def skipped_count_for_suite(suite)
53
+ suite.select {|example| example.metadata[:execution_result][:status] == "pending"}.size
54
+ end
55
+
56
+ def dump_summary(duration, example_count, failure_count, pending_count)
57
+ builder = Builder::XmlMarkup.new :indent => 2
58
+ builder.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
59
+ builder.testsuites :errors => 0, :failures => failure_count, :skipped => pending_count, :tests => example_count, :time => duration, :timestamp => Time.now.iso8601 do
60
+ @test_suite_results.each do |suite_name, tests|
61
+ builder.testsuite :name => suite_name, :tests => tests.size, :errors => 0, :failures => fail_count_for_suite(tests), :skipped => skipped_count_for_suite(tests) do
62
+ builder.properties
63
+ tests.each do |test|
64
+ builder.testcase :name => test.metadata[:full_description], :time => test.metadata[:execution_result][:run_time] do
65
+ case test.metadata[:execution_result][:status]
66
+ when "pending" then builder.skipped
67
+ when "failed"
68
+ builder.failure :message => "failed #{test.metadata[:full_description]}", :type => "failed" do
69
+ builder.cdata! failure_details_for test
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ output.puts builder.target!
78
+ end
79
+ end
80
+
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yarjuf
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nat Ritmeyer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 2.0.0
30
+ description: Yet Another RSpec JUnit Formatter (for Hudson/Jenkins)
31
+ email:
32
+ - nat@natontesting.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - lib/yarjuf.rb
38
+ - LICENSE.txt
39
+ - HISTORY.txt
40
+ - README.md
41
+ homepage: http://github.com/natritmeyer/yarjuf
42
+ licenses: []
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.24
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Yet Another RSpec JUnit Formatter (for Hudson/Jenkins)
65
+ test_files: []