yarjuf 1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []