rspec_junit 2.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f8bab019f7ceef3db7a655d093b52f3b5d89a8c8
4
+ data.tar.gz: 6f37c4d43b2400cd440e014a51c74c8b984b3616
5
+ SHA512:
6
+ metadata.gz: 4edfe85d24ee0e142a881166133f86336606a2d899b2256820e8d503132409a05d55dbf31abe7b07c7e0623024340f628b6bc48ef5ab88840084b8bd1e470914
7
+ data.tar.gz: 45086b0c95485758c71141556d908eb4479e28a6dc94ac8603b58b01da6590c0e031f8512dfe737fe6091c05be28ec8e38b7ea584c71bc18565fdc2da439694a
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color --require spec_helper
2
+
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.2
7
+ gemfile:
8
+ - Gemfile
9
+ branches:
10
+ only:
11
+ - master
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/HISTORY.txt ADDED
@@ -0,0 +1,25 @@
1
+ 1.0
2
+ - Initial release
3
+
4
+ 1.0.1
5
+ - Bug in RSpec 2.12 needs coding around
6
+
7
+ 1.0.2
8
+ - Added dependency on the 'builder' gem
9
+
10
+ 1.0.3
11
+ - Bug fix in RSpec 2.12.1 means we can go back to how it was before 1.0.1
12
+
13
+ 1.0.4
14
+ - No functional changes, just a big refactor to make the code more
15
+ maintainable.
16
+
17
+ 1.0.5
18
+ - some refactoring, no functional changes
19
+
20
+ 1.0.6
21
+ - Last version that works with RSpec 2. Some internal refactoring.
22
+
23
+ 2.0.0
24
+ - Now works with rspec 3 (thanks @bsnape )
25
+
data/LICENSE.txt ADDED
@@ -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
+
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # yarjuf
2
+
3
+ _Yet Another RSpec JUnit Formatter_
4
+
5
+ [![Build Status](https://travis-ci.org/natritmeyer/yarjuf.png)](https://travis-ci.org/natritmeyer/yarjuf)
6
+
7
+ ## Intro
8
+
9
+ I've never found a gem that can be relied on to generate JUnit
10
+ 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
11
+ useful to others. But it was a hack and thought I'd rewrite it, make it
12
+ conform to the JUnit format spec a bit better, and make it
13
+ distributable as a gem. Thus: [yet-another-rspec-junit-formatter](https://github.com/natritmeyer/yarjuf)
14
+
15
+ ## Installation
16
+
17
+ Using rubygems:
18
+
19
+ `gem install yarjuf`
20
+
21
+ Using bundler:
22
+
23
+ Add the following line to your `Gemfile`:
24
+
25
+ `gem 'yarjuf'`
26
+
27
+ ## Usage
28
+
29
+ There are a few ways to use custom formatters in RSpec; what follows is
30
+ the 'best' way...
31
+
32
+ ### Loading yarjuf
33
+
34
+ Before you can use yarjuf, RSpec needs to know about it. The best way to
35
+ do that is to use the functionality that RSpec provides to load
36
+ libraries.
37
+
38
+ #### Modifying the `.rspec` file
39
+
40
+ When RSpec executes, it looks for a file in the current working
41
+ directory (project root) called `.rspec` that contains rspec
42
+ configuration. It is a good idea to add the following to it:
43
+
44
+ `--require spec_helper`
45
+
46
+ Doing so will make sure that the `spec/spec_helper.rb` file will get
47
+ required when RSpec starts.
48
+
49
+ #### Modifying the `spec/spec_helper.rb` file
50
+
51
+ Add the following to your `spec/spec_helper.rb`:
52
+
53
+ ```ruby
54
+ require 'yarjuf'
55
+ ```
56
+
57
+ That will make sure that yarjuf is loaded when RSpec starts and can be
58
+ used as a formatter.
59
+
60
+ ### Generating JUnit output using yarjuf
61
+
62
+ RSpec tests can be executed in a number of ways. Here's how to get JUnit
63
+ output for each of those different ways - assuming you've loaded yarjuf
64
+ as specified above).
65
+
66
+ #### Running rspec tests from the command line
67
+
68
+ In this scenario, you just want to run `rspec` from the command line and
69
+ get JUnit output. To do that you'll need to use the `-f JUnit` option
70
+ to generate JUnit output and to write it to a file you can use the
71
+ `-o results.xml` option. So to run all your tests and get JUnit output
72
+ written to a file, execute the following:
73
+
74
+ `rspec -f JUnit -o results.xml`
75
+
76
+ #### Running rspec tests using Rake
77
+
78
+ In this scenario, you want to run your rspec tests using rake. To do
79
+ that you'll need to add an option to your rake task:
80
+
81
+ ```ruby
82
+ RSpec::Core::RakeTask.new(:spec) do |t|
83
+ t.rspec_opts = %w[-f JUnit -o results.xml]
84
+ end
85
+ ```
86
+
87
+ That will write out JUnit formatted results to a file called
88
+ `results.xml`.
89
+
90
+ #### Jenkins integration
91
+
92
+ To use yarjuf with Jenkins(/Hudson), simply tick the 'Publish JUnit test
93
+ result report' option in the Jenkins task configuration page and in the
94
+ 'Test report XMLs' field specify the file name that you expect the JUnit
95
+ formatted results to be written to, ie: the file path and name specified
96
+ in the `-o` option above.
97
+
98
+ ## Acknowledgements
99
+
100
+ * Thanks to [@bsnape](https://github.com/bsnape) for the rspec 3 compatibility patch
101
+ * Thanks to [@adeoke](https://github.com/adeoke) for suggesting a slightly less sucky gem name than the
102
+ one I originally came up with
103
+ * Thanks to [@dchamb84](https://github.com/dchamb84) for helping me debug the original hack
104
+ * Thanks to [@nathanbain](https://github.com/nathanbain) for spurring me on to write the original hack
105
+
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'cucumber/rake/task'
3
+ require 'rspec/core/rake_task'
4
+
5
+ namespace :cuke do
6
+ Cucumber::Rake::Task.new(:all) do |t|
7
+ t.cucumber_opts = "--format pretty"
8
+ end
9
+
10
+ Cucumber::Rake::Task.new(:wip) do |t|
11
+ t.cucumber_opts = "--format pretty -t @wip"
12
+ end
13
+ end
14
+
15
+ namespace :spec do
16
+ RSpec::Core::RakeTask.new(:all) do |t|
17
+ t.pattern = "spec/**/*_spec.rb"
18
+ t.ruby_opts = "-I lib"
19
+ end
20
+ end
21
+
22
+ task :default => ['spec:all', 'cuke:all']
23
+
@@ -0,0 +1,24 @@
1
+ Feature: Basic use of Yarjuf
2
+ As a tester
3
+ In order to be able to get junit formatted results from rspec
4
+ I want to be able to use yarjuf
5
+
6
+ Background:
7
+ Given a file named "spec/basic_spec.rb" with:
8
+ """
9
+ describe "basic usage" do
10
+ it "should work" do
11
+ expect(true).to be true
12
+ end
13
+ end
14
+ """
15
+
16
+ Scenario: Requiring Yarjuf
17
+ When I run `rspec spec/basic_spec.rb -r ../../lib/yarjuf -f JUnit`
18
+ Then the exit status should be 0
19
+
20
+ Scenario: Writing output to a file
21
+ When I run `rspec spec/basic_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
22
+ Then the exit status should be 0
23
+ And a file named "results.xml" should exist
24
+
@@ -0,0 +1,82 @@
1
+ Feature: Individual suites
2
+ As a tester
3
+ In order to see relevant tests grouped together in suites
4
+ I want to be able to differentiate between different `describe` blocks
5
+
6
+ Scenario: Differentiating between 2 suites
7
+ Given a file named "spec/suite_one_spec.rb" with:
8
+ """
9
+ describe "suite one" do
10
+ it "should contain one test" do
11
+ expect(1).to eq 1
12
+ end
13
+ end
14
+ """
15
+ And a file named "spec/suite_two_spec.rb" with:
16
+ """
17
+ describe "suite two" do
18
+ it "should also contain one test" do
19
+ expect(1).to eq 1
20
+ end
21
+ end
22
+ """
23
+ When I run `rspec spec/suite_one_spec.rb spec/suite_two_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
24
+ Then the junit output file contains two testsuite elements named 'suite one' and 'suite two'
25
+ And the junit output file has one test against each suite
26
+
27
+ Scenario: Correct test result counts at individual suite level
28
+ Given a file named "spec/suite_one_spec.rb" with:
29
+ """
30
+ describe "suite one" do
31
+ it "should contain one passing test" do
32
+ expect(1).to eq 1
33
+ end
34
+
35
+ it "should contain one of two failing tests" do
36
+ expect(1).to eq 2
37
+ end
38
+
39
+ it "should contain two of two failing tests" do
40
+ expect(1).to eq 2
41
+ end
42
+
43
+ it "should contain 1 pending test" do
44
+ pending
45
+ fail
46
+ end
47
+ end
48
+ """
49
+ And a file named "spec/suite_two_spec.rb" with:
50
+ """
51
+ describe "suite two" do
52
+ it "should contain one of 3 passing tests" do
53
+ expect(1).to eq 1
54
+ end
55
+
56
+ it "should contain two of 3 passing tests" do
57
+ expect(1).to eq 1
58
+ end
59
+
60
+ it "should contain three of 3 passing tests" do
61
+ expect(1).to eq 1
62
+ end
63
+
64
+ it "should contain one failing test" do
65
+ expect(1).to eq 2
66
+ end
67
+
68
+ it "should contain one of two pending tests" do
69
+ pending
70
+ fail
71
+ end
72
+
73
+ it "should contain two of two pending tests" do
74
+ pending
75
+ fail
76
+ end
77
+ end
78
+ """
79
+ When I run `rspec spec/suite_one_spec.rb spec/suite_two_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
80
+ Then the junit output file contains two testsuite elements named 'suite one' and 'suite two'
81
+ And the junit output file has the correct test counts against each suite
82
+
@@ -0,0 +1,74 @@
1
+ Feature: Individual Tests
2
+ As a tester
3
+ In order to be able to see details of individual tests
4
+ I want to write out test results
5
+
6
+ Scenario: Simple test name
7
+ Given a file named "spec/simple_test_name_spec.rb" with:
8
+ """
9
+ describe "suite one" do
10
+ it "simple name" do
11
+ expect(1).to eq 1
12
+ end
13
+ end
14
+ """
15
+ When I run `rspec spec/simple_test_name_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
16
+ Then the junit output file contains a test result with a simple name
17
+
18
+ Scenario: Nested tests
19
+ Given a file named "spec/nested_spec.rb" with:
20
+ """
21
+ describe "something" do
22
+ context "that" do
23
+ context "is" do
24
+ context "really" do
25
+ context "deep" do
26
+ it "should still be displayed nicely" do
27
+ expect(1).to eq 1
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ """
35
+ When I run `rspec spec/nested_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
36
+ Then the junit output file has a nicely rendered nested test name
37
+
38
+ Scenario: Test duration
39
+ Given a file named "spec/test_duration_spec.rb" with:
40
+ """
41
+ describe "suite one" do
42
+ it "should do something" do
43
+ expect(1).to eq 1
44
+ end
45
+ end
46
+ """
47
+ When I run `rspec spec/test_duration_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
48
+ Then the junit output file contains a test with a duration
49
+
50
+ Scenario: Pending test
51
+ Given a file named "spec/pending_test_spec.rb" with:
52
+ """
53
+ describe "suite one" do
54
+ it "should be pending" do
55
+ pending
56
+ fail
57
+ end
58
+ end
59
+ """
60
+ When I run `rspec spec/pending_test_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
61
+ Then the junit output file contains a pending test
62
+
63
+ Scenario: Failing test
64
+ Given a file named "spec/failing_test_spec.rb" with:
65
+ """
66
+ describe "suite one" do
67
+ it "should be failing" do
68
+ expect(1).to eq 2
69
+ end
70
+ end
71
+ """
72
+ When I run `rspec spec/failing_test_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
73
+ Then the junit output file contains a failing test
74
+
@@ -0,0 +1,24 @@
1
+ Then /^the junit output file contains two testsuite elements named 'suite one' and 'suite two'$/ do
2
+ step 'I parse the junit results file'
3
+ expect(@results.xpath("/testsuites/testsuite").size).to eq 2
4
+ expect(@results.xpath("/testsuites/testsuite/@name").map(&:text).sort).to match_array ["suite one", "suite two"]
5
+ end
6
+
7
+ Then /^the junit output file has one test against each suite$/ do
8
+ step 'I parse the junit results file'
9
+ expect(@results.xpath("/testsuites/testsuite/@tests").map(&:text)).to match_array ["1", "1"]
10
+ end
11
+
12
+ Then /^the junit output file has the correct test counts against each suite$/ do
13
+ step 'I parse the junit results file'
14
+ #suite one
15
+ expect(@results.at_xpath("/testsuites/testsuite[@name='suite one']/@tests").value).to eq "4"
16
+ expect(@results.at_xpath("/testsuites/testsuite[@name='suite one']/@failures").value).to eq "2"
17
+ expect(@results.at_xpath("/testsuites/testsuite[@name='suite one']/@skipped").value).to eq "1"
18
+
19
+ #suite two
20
+ expect(@results.at_xpath("/testsuites/testsuite[@name='suite two']/@tests").value).to eq "6"
21
+ expect(@results.at_xpath("/testsuites/testsuite[@name='suite two']/@failures").value).to eq "1"
22
+ expect(@results.at_xpath("/testsuites/testsuite[@name='suite two']/@skipped").value).to eq "2"
23
+ end
24
+
@@ -0,0 +1,28 @@
1
+ Then /^the junit output file contains a test result with a simple name$/ do
2
+ step 'I parse the junit results file'
3
+ expect(@results.at_xpath("/testsuites/testsuite[@name='suite one']/testcase/@name").value).to eq "suite one simple name"
4
+ end
5
+
6
+ Then /^the junit output file has a nicely rendered nested test name$/ do
7
+ step 'I parse the junit results file'
8
+ expect(@results.at_xpath("/testsuites/testsuite/testcase/@name").value).to eq "something that is really deep should still be displayed nicely"
9
+ end
10
+
11
+ Then /^the junit output file contains a test with a duration$/ do
12
+ step 'I parse the junit results file'
13
+ expect(@results.at_xpath("/testsuites/testsuite/testcase/@time").value).to match /[.0-9]+/
14
+ end
15
+
16
+ Then /^the junit output file contains a pending test$/ do
17
+ step 'I parse the junit results file'
18
+ expect(@results.at_xpath("/testsuites/testsuite/testcase/skipped")).to_not be_nil
19
+ end
20
+
21
+ Then /^the junit output file contains a failing test$/ do
22
+ step 'I parse the junit results file'
23
+ expect(@results.at_xpath("/testsuites/testsuite/testcase/failure")).to_not be_nil
24
+ expect(@results.at_xpath("/testsuites/testsuite/testcase/failure/@message").value).to eq "failed suite one should be failing"
25
+ expect(@results.at_xpath("/testsuites/testsuite/testcase/failure/@type").value).to eq "failed"
26
+ expect(@results.at_xpath("/testsuites/testsuite/testcase/failure").text).to match /expected.*2.*got.*1.*using.*==.*spec\/failing_test_spec\.rb:3/m
27
+ end
28
+
@@ -0,0 +1,6 @@
1
+ When /^I parse the junit results file$/ do
2
+ results_file = 'tmp/aruba/results.xml'
3
+ expect(File).to exist results_file
4
+ @results ||= Nokogiri::XML File.open(results_file)
5
+ end
6
+
@@ -0,0 +1,39 @@
1
+ Then /^the junit output contains the testsuite element$/ do
2
+ step 'I parse the junit results file'
3
+ expect(@results.xpath("/testsuites").size).to eq 1
4
+ end
5
+
6
+ Then /^the junit output reports one passing test$/ do
7
+ step 'I parse the junit results file'
8
+ expect(@results.at_xpath("/testsuites/@errors").value).to eq "0"
9
+ expect(@results.at_xpath("/testsuites/@failures").value).to eq "0"
10
+ expect(@results.at_xpath("/testsuites/@skipped").value).to eq "0"
11
+ expect(@results.at_xpath("/testsuites/@tests").value).to eq "1"
12
+ end
13
+
14
+ Then /^the junit output reports one failing test$/ do
15
+ step 'I parse the junit results file'
16
+ expect(@results.at_xpath("/testsuites/@errors").value).to eq "0"
17
+ expect(@results.at_xpath("/testsuites/@failures").value).to eq "1"
18
+ expect(@results.at_xpath("/testsuites/@skipped").value).to eq "0"
19
+ expect(@results.at_xpath("/testsuites/@tests").value).to eq "1"
20
+ end
21
+
22
+ Then /^the junit output reports one pending test$/ do
23
+ step 'I parse the junit results file'
24
+ expect(@results.at_xpath("/testsuites/@errors").value).to eq "0"
25
+ expect(@results.at_xpath("/testsuites/@failures").value).to eq "0"
26
+ expect(@results.at_xpath("/testsuites/@skipped").value).to eq "1"
27
+ expect(@results.at_xpath("/testsuites/@tests").value).to eq "1"
28
+ end
29
+
30
+ Then /^the junit output testsuite element contains a duration$/ do
31
+ step 'I parse the junit results file'
32
+ expect(@results.at_xpath("/testsuites/@time").value).to match /[.0-9]+/
33
+ end
34
+
35
+ Then /^the junit output testsuite element contains a timestamp$/ do
36
+ step 'I parse the junit results file'
37
+ expect(@results.at_xpath("/testsuites/@timestamp").value).to match /\d{4}-\d{2}-\d{2}T\d+:\d+:\d+\+\d+:\d+/
38
+ end
39
+
@@ -0,0 +1,78 @@
1
+ Feature: Suite Summary
2
+ As a tester
3
+ In order to make the summary detail visible in jenkins
4
+ I want to output the suite summary level detail to the output
5
+
6
+ Scenario: testsuites element present
7
+ Given a file named "spec/suite_element_spec.rb" with:
8
+ """
9
+ describe "suite element" do
10
+ it "should be present" do
11
+ expect(1).to eq 1
12
+ end
13
+ end
14
+ """
15
+ When I run `rspec spec/suite_element_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
16
+ Then the junit output contains the testsuite element
17
+
18
+ Scenario: One passing test
19
+ Given a file named "spec/one_passing_test_spec.rb" with:
20
+ """
21
+ describe "suite level details for 1 passing test" do
22
+ it "should pass" do
23
+ expect(1).to eq 1
24
+ end
25
+ end
26
+ """
27
+ When I run `rspec spec/one_passing_test_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
28
+ Then the junit output reports one passing test
29
+
30
+ Scenario: One failing test
31
+ Given a file named "spec/one_failing_test_spec.rb" with:
32
+ """
33
+ describe "suite level details for 1 failing test" do
34
+ it "should fail" do
35
+ expect(1).to eq 2
36
+ end
37
+ end
38
+ """
39
+ When I run `rspec spec/one_failing_test_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
40
+ Then the junit output reports one failing test
41
+
42
+ Scenario: One pending test
43
+ Given a file named "spec/one_pending_test_spec.rb" with:
44
+ """
45
+ describe "suite level details for 1 pending test" do
46
+ it "should be pending" do
47
+ pending
48
+ fail
49
+ end
50
+ end
51
+ """
52
+ When I run `rspec spec/one_pending_test_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
53
+ Then the junit output reports one pending test
54
+
55
+ Scenario: Test suite duration
56
+ Given a file named "spec/suite_duration_spec.rb" with:
57
+ """
58
+ describe "suite element duration" do
59
+ it "should contain a duration" do
60
+ expect(1).to eq 1
61
+ end
62
+ end
63
+ """
64
+ When I run `rspec spec/suite_duration_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
65
+ Then the junit output testsuite element contains a duration
66
+
67
+ Scenario: Test suite time stamp
68
+ Given a file named "spec/suite_timestamp_spec.rb" with:
69
+ """
70
+ describe "suite element timestamp" do
71
+ it "should contain a timestamp" do
72
+ expect(1).to eq 1
73
+ end
74
+ end
75
+ """
76
+ When I run `rspec spec/suite_timestamp_spec.rb -r ../../lib/yarjuf -f JUnit -o results.xml`
77
+ Then the junit output testsuite element contains a timestamp
78
+
@@ -0,0 +1,6 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'aruba/cucumber'
5
+ require 'nokogiri'
6
+
data/lib/yarjuf.rb ADDED
@@ -0,0 +1,9 @@
1
+ # external dependencies
2
+ require 'time'
3
+ require 'builder'
4
+ require 'rspec/core'
5
+ require 'rspec/core/formatters'
6
+
7
+ # internal dependencies
8
+ require 'yarjuf/j_unit'
9
+ require 'yarjuf/version'
@@ -0,0 +1,119 @@
1
+ # An RSpec formatter for generating results in JUnit format
2
+ class JUnit
3
+ RSpec::Core::Formatters.register self, :example_passed, :example_failed, :example_pending, :dump_summary
4
+
5
+ def initialize(output)
6
+ @output = output
7
+ @test_suite_results = {}
8
+ @builder = Builder::XmlMarkup.new :indent => 2
9
+ end
10
+
11
+ def example_passed(example_notification)
12
+ add_to_test_suite_results example_notification
13
+ end
14
+
15
+ def example_failed(example_notification)
16
+ add_to_test_suite_results example_notification
17
+ end
18
+
19
+ def example_pending(example_notification)
20
+ add_to_test_suite_results example_notification
21
+ end
22
+
23
+ def dump_summary(summary)
24
+ build_results(summary.duration, summary.examples.size, summary.failed_examples.size, summary.pending_examples.size)
25
+ @output.puts @builder.target!
26
+ end
27
+
28
+ protected
29
+
30
+ def add_to_test_suite_results(example_notification)
31
+ suite_name = JUnit.root_group_name_for example_notification
32
+ @test_suite_results[suite_name] = [] unless @test_suite_results.keys.include? suite_name
33
+ @test_suite_results[suite_name] << example_notification.example
34
+ end
35
+
36
+ def failure_details_for(example)
37
+ exception = example.exception
38
+ formatted_backtrace = RSpec::Core::BacktraceFormatter.new.format_backtrace exception.backtrace
39
+ exception.nil? ? '' : "#{exception.message}\n#{formatted_backtrace}"
40
+ end
41
+
42
+ # utility methods
43
+
44
+ def self.count_in_suite_of_type(suite, test_case_result_type)
45
+ suite.select { |example| example.metadata[:execution_result].status == test_case_result_type }.size
46
+ end
47
+
48
+ def self.root_group_name_for(example_notification)
49
+ example_notification.example.metadata[:example_group][:description]
50
+ end
51
+
52
+ # methods to build the xml for test suites and individual tests
53
+
54
+ def build_results(duration, example_count, failure_count, pending_count)
55
+ @builder.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
56
+ @builder.testsuites(
57
+ :errors => 0,
58
+ :failures => failure_count,
59
+ :skipped => pending_count,
60
+ :tests => example_count,
61
+ :time => duration,
62
+ :timestamp => Time.now.iso8601) do
63
+ build_all_suites
64
+ end
65
+ end
66
+
67
+ def build_all_suites
68
+ @test_suite_results.each do |suite_name, tests|
69
+ build_test_suite(suite_name, tests)
70
+ end
71
+ end
72
+
73
+ def build_test_suite(suite_name, tests)
74
+ failure_count = JUnit.count_in_suite_of_type(tests, :failed)
75
+ skipped_count = JUnit.count_in_suite_of_type(tests, :pending)
76
+
77
+ @builder.testsuite(
78
+ :location => tests.first.example_group.location,
79
+ :name => suite_name,
80
+ :tests => tests.size,
81
+ :errors => 0,
82
+ :failures => failure_count,
83
+ :skipped => skipped_count) do
84
+ @builder.properties
85
+ build_all_tests tests
86
+ end
87
+ end
88
+
89
+ def build_all_tests(tests)
90
+ tests.each do |test|
91
+ build_test test
92
+ end
93
+ end
94
+
95
+ def build_test(test)
96
+ test_name = test.metadata[:full_description]
97
+ execution_time = test.metadata[:execution_result].run_time
98
+ test_status = test.metadata[:execution_result].status
99
+ location = test.location
100
+
101
+ @builder.testcase(:name => test_name, :time => execution_time, :location => location) do
102
+ case test_status
103
+ when :pending
104
+ @builder.skipped
105
+ when :failed
106
+ build_failed_test test
107
+ end
108
+ end
109
+ end
110
+
111
+ def build_failed_test(test)
112
+ failure_message = "failed #{test.metadata[:full_description]}"
113
+
114
+ @builder.failure(:message => failure_message, :type => 'failed') do
115
+ @builder.cdata!(failure_details_for(test))
116
+ end
117
+ end
118
+
119
+ end
@@ -0,0 +1,3 @@
1
+ module Yarjuf
2
+ VERSION = '2.0.0'
3
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'yarjuf/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'rspec_junit'
8
+ gem.version = Yarjuf::VERSION
9
+ gem.platform = Gem::Platform::RUBY
10
+ gem.authors = ['Nat Ritmeyer', 'Ben Snape']
11
+ gem.email = ['nat@natontesting.com']
12
+ gem.homepage = 'http://github.com/natritmeyer/yarjuf'
13
+ gem.summary = 'Yet Another RSpec JUnit Formatter (for Hudson/Jenkins)'
14
+ gem.description = 'Yet Another RSpec JUnit Formatter (for Hudson/Jenkins)'
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ['lib']
20
+
21
+ gem.add_runtime_dependency('rspec', '~> 3')
22
+ gem.add_runtime_dependency('builder')
23
+
24
+ gem.add_development_dependency('nokogiri', '~> 1.5.10') # for Ruby 1.8.7
25
+ gem.add_development_dependency('rake', '~> 10.3.2')
26
+ gem.add_development_dependency('cucumber', '~> 1.3.16')
27
+ gem.add_development_dependency('aruba', '~> 0.6.0')
28
+ gem.add_development_dependency('simplecov', '~> 0.8.2') # for Ruby 1.8.7
29
+ gem.add_development_dependency('reek', ['= 1.3.7']) # for Ruby 1.8.7
30
+ gem.add_development_dependency('rainbow', '~> 1.99.2') # for Ruby 1.8.7
31
+ end
@@ -0,0 +1,22 @@
1
+ describe JUnit do
2
+ context "interface conformity" do
3
+ subject { JUnit.new "some output" }
4
+
5
+ it "should respond to example passed" do
6
+ should respond_to :example_passed
7
+ end
8
+
9
+ it "should respond to example failed" do
10
+ should respond_to :example_failed
11
+ end
12
+
13
+ it "should respond to example pending" do
14
+ should respond_to :example_pending
15
+ end
16
+
17
+ it "should respond to dump summary" do
18
+ should respond_to :dump_summary
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,2 @@
1
+ require 'yarjuf'
2
+
metadata ADDED
@@ -0,0 +1,204 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec_junit
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nat Ritmeyer
8
+ - Ben Snape
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-01-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '3'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: builder
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: nokogiri
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: 1.5.10
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: 1.5.10
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 10.3.2
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 10.3.2
70
+ - !ruby/object:Gem::Dependency
71
+ name: cucumber
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: 1.3.16
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 1.3.16
84
+ - !ruby/object:Gem::Dependency
85
+ name: aruba
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 0.6.0
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: 0.6.0
98
+ - !ruby/object:Gem::Dependency
99
+ name: simplecov
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: 0.8.2
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: 0.8.2
112
+ - !ruby/object:Gem::Dependency
113
+ name: reek
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '='
117
+ - !ruby/object:Gem::Version
118
+ version: 1.3.7
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '='
124
+ - !ruby/object:Gem::Version
125
+ version: 1.3.7
126
+ - !ruby/object:Gem::Dependency
127
+ name: rainbow
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: 1.99.2
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: 1.99.2
140
+ description: Yet Another RSpec JUnit Formatter (for Hudson/Jenkins)
141
+ email:
142
+ - nat@natontesting.com
143
+ executables: []
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - ".gitignore"
148
+ - ".rspec"
149
+ - ".travis.yml"
150
+ - Gemfile
151
+ - HISTORY.txt
152
+ - LICENSE.txt
153
+ - README.md
154
+ - Rakefile
155
+ - features/basic.feature
156
+ - features/individual_suites.feature
157
+ - features/individual_tests.feature
158
+ - features/step_definitions/individual_suite_details_steps.rb
159
+ - features/step_definitions/individual_tests_steps.rb
160
+ - features/step_definitions/infrastructure_steps.rb
161
+ - features/step_definitions/suite_level_details_steps.rb
162
+ - features/suite_level_details.feature
163
+ - features/support/env.rb
164
+ - lib/yarjuf.rb
165
+ - lib/yarjuf/j_unit.rb
166
+ - lib/yarjuf/version.rb
167
+ - rspec_junit.gemspec
168
+ - spec/formatter_conformity_spec.rb
169
+ - spec/spec_helper.rb
170
+ homepage: http://github.com/natritmeyer/yarjuf
171
+ licenses: []
172
+ metadata: {}
173
+ post_install_message:
174
+ rdoc_options: []
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ required_rubygems_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ requirements: []
188
+ rubyforge_project:
189
+ rubygems_version: 2.4.3
190
+ signing_key:
191
+ specification_version: 4
192
+ summary: Yet Another RSpec JUnit Formatter (for Hudson/Jenkins)
193
+ test_files:
194
+ - features/basic.feature
195
+ - features/individual_suites.feature
196
+ - features/individual_tests.feature
197
+ - features/step_definitions/individual_suite_details_steps.rb
198
+ - features/step_definitions/individual_tests_steps.rb
199
+ - features/step_definitions/infrastructure_steps.rb
200
+ - features/step_definitions/suite_level_details_steps.rb
201
+ - features/suite_level_details.feature
202
+ - features/support/env.rb
203
+ - spec/formatter_conformity_spec.rb
204
+ - spec/spec_helper.rb