rspec_junit_formatter_jenkins 0.1.6 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -6
- data/lib/rspec_junit_formatter.rb +63 -6
- data/lib/rspec_junit_formatter/rspec2.rb +54 -0
- data/lib/rspec_junit_formatter/rspec3.rb +70 -0
- metadata +34 -20
- data/lib/rspec/core/formatters/j_unit_formatter.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fc7f2e232b26f66a41b501066a0063523f321ad
|
4
|
+
data.tar.gz: 36a2219be70c61d6da80cd641f36f487e182306c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee353ff2896acebfb23ff25f68afd1e79e8d55ed046bd663e71231c546b5ce57cdb95c4ac6ffdcbe8c7aefd53af11352d44cf1752260e2ab79519e91558cf265
|
7
|
+
data.tar.gz: bd54e173d3fe0441e0deb5fca936d931f428aabf4023c6beea8baea3fb1e3b352e89e50e40ee66d0138d3377746daa59778ba29b4f6941f041cf01faa4a3a2c0
|
data/README.md
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# RSpec JUnit Formatter
|
2
2
|
|
3
|
-
[
|
3
|
+
[![Build results](http://img.shields.io/travis/sj26/rspec_junit_formatter.svg)](https://travis-ci.org/sj26/rspec_junit_formatter)
|
4
|
+
[![Gem version](http://img.shields.io/gem/v/rspec_junit_formatter.svg)](https://rubygems.org/gems/rspec_junit_formatter)
|
4
5
|
|
5
|
-
|
6
|
+
[RSpec][rspec] 2 & 3 results that [Jenkins][jenkins] can read. Probably a few other CI servers, too.
|
7
|
+
|
8
|
+
Inspired by the work of [Diego Souza][dgvncsz0f] on [RSpec Formatters][dgvncsz0f/rspec_formatters] after frustration with [CI Reporter][ci_reporter].
|
6
9
|
|
7
10
|
## Usage
|
8
11
|
|
@@ -25,7 +28,9 @@ In your .rspec, usually alongside another formatter, add:
|
|
25
28
|
--format RspecJunitFormatter
|
26
29
|
--out rspec.xml
|
27
30
|
|
28
|
-
|
31
|
+
You can use it in combination with other formatters:
|
32
|
+
|
33
|
+
rspec --format progress --format RspecJunitFormatter --out rspec.xml
|
29
34
|
|
30
35
|
## Roadmap
|
31
36
|
|
@@ -38,9 +43,9 @@ The MIT License, see [LICENSE][license].
|
|
38
43
|
|
39
44
|
[rspec]: http://rspec.info/
|
40
45
|
[jenkins]: http://jenkins-ci.org/
|
41
|
-
[
|
42
|
-
[
|
43
|
-
[ci_reporter]:
|
46
|
+
[dgvncsz0f]: https://github.com/dgvncsz0f
|
47
|
+
[dgvncsz0f/rspec_formatters]: https://github.com/dgvncsz0f/rspec_formatters
|
48
|
+
[ci_reporter]: https://github.com/nicksieger/ci_reporter
|
44
49
|
[bundler]: http://gembundler.com/
|
45
50
|
[fuubar]: http://jeffkreeftmeijer.com/2010/fuubar-the-instafailing-rspec-progress-bar-formatter/
|
46
51
|
[license]: https://github.com/sj26/rspec-junit-formatter/blob/master/LICENSE
|
@@ -1,8 +1,65 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "time"
|
2
|
+
require "builder"
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "rspec/core"
|
5
|
+
require "rspec/core/formatters/base_formatter"
|
6
6
|
|
7
|
-
#
|
8
|
-
|
7
|
+
# Dumps rspec results as a JUnit XML file.
|
8
|
+
# Based on XML schema: http://windyroad.org/dl/Open%20Source/JUnit.xsd
|
9
|
+
class RSpecJUnitFormatter < RSpec::Core::Formatters::BaseFormatter
|
10
|
+
# rspec 2 and 3 implements are in separate files.
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def xml
|
15
|
+
@xml ||= Builder::XmlMarkup.new target: output, indent: 2
|
16
|
+
end
|
17
|
+
|
18
|
+
def xml_dump
|
19
|
+
xml.instruct!
|
20
|
+
xml.testsuite name: "rspec#{ENV['TEST_ENV_NUMBER']}", tests: example_count, failures: failure_count, errors: 0, time: "%.6f" % duration, timestamp: started.iso8601 do
|
21
|
+
xml.comment! "Randomized with seed #{RSpec.configuration.seed}"
|
22
|
+
xml.properties
|
23
|
+
xml_dump_examples
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def xml_dump_examples
|
28
|
+
examples.each do |example|
|
29
|
+
send :"xml_dump_#{result_of(example)}", example
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def xml_dump_passed(example)
|
34
|
+
xml_dump_example(example)
|
35
|
+
end
|
36
|
+
|
37
|
+
def xml_dump_pending(example)
|
38
|
+
xml_dump_example(example) do
|
39
|
+
xml.skipped
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def xml_dump_failed(example)
|
44
|
+
exception = exception_for(example)
|
45
|
+
backtrace = formatted_backtrace_for(example)
|
46
|
+
|
47
|
+
xml_dump_example(example) do
|
48
|
+
xml.error message: exception.to_s, type: exception.class.name do
|
49
|
+
xml.text! "#{exception.message.encode(:xml => :text)}\n#{backtrace.join.encode(:xml => :text)}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def xml_dump_example(example, &block)
|
55
|
+
xml.testcase classname: classname_for(example), name: description_for(example), file: example_group_file_path_for(example), time: "%.6f" % duration_for(example), &block
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
RspecJunitFormatter = RSpecJUnitFormatter
|
60
|
+
|
61
|
+
if RSpec::Core::Version::STRING.start_with? "3."
|
62
|
+
require "rspec_junit_formatter/rspec3"
|
63
|
+
else RSpec::Core::Version::STRING.start_with? "2."
|
64
|
+
require "rspec_junit_formatter/rspec2"
|
65
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class RSpecJUnitFormatter < RSpec::Core::Formatters::BaseFormatter
|
2
|
+
attr_reader :started
|
3
|
+
|
4
|
+
def start(example_count)
|
5
|
+
@started = Time.now
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def dump_summary(duration, example_count, failure_count, pending_count)
|
10
|
+
super
|
11
|
+
xml_dump
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def xml_dump_examples
|
17
|
+
examples.each do |example|
|
18
|
+
send :"xml_dump_#{example.execution_result[:status]}", example
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def result_of(example)
|
23
|
+
example.execution_result[:status]
|
24
|
+
end
|
25
|
+
|
26
|
+
def example_group_file_path_for(example)
|
27
|
+
meta = example.metadata
|
28
|
+
while meta[:example_group]
|
29
|
+
meta = meta[:example_group]
|
30
|
+
end
|
31
|
+
meta[:file_path]
|
32
|
+
end
|
33
|
+
|
34
|
+
def classname_for(example)
|
35
|
+
fp = example_group_file_path_for(example)
|
36
|
+
fp.sub(%r{\.[^/.]+\Z}, "").gsub("/", ".").gsub(/\A\.+|\.+\Z/, "")
|
37
|
+
end
|
38
|
+
|
39
|
+
def duration_for(example)
|
40
|
+
example.execution_result[:run_time]
|
41
|
+
end
|
42
|
+
|
43
|
+
def description_for(example)
|
44
|
+
example.full_description
|
45
|
+
end
|
46
|
+
|
47
|
+
def exception_for(example)
|
48
|
+
example.execution_result[:exception]
|
49
|
+
end
|
50
|
+
|
51
|
+
def formatted_backtrace_for(example)
|
52
|
+
format_backtrace exception_for(example).backtrace, example
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class RSpecJUnitFormatter < RSpec::Core::Formatters::BaseFormatter
|
2
|
+
RSpec::Core::Formatters.register self,
|
3
|
+
:start,
|
4
|
+
:stop,
|
5
|
+
:dump_summary
|
6
|
+
|
7
|
+
def start(notification)
|
8
|
+
@start_notification = notification
|
9
|
+
@started = Time.now
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def stop(notification)
|
14
|
+
@examples_notification = notification
|
15
|
+
end
|
16
|
+
|
17
|
+
def dump_summary(notification)
|
18
|
+
@summary_notification = notification
|
19
|
+
xml_dump
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :started
|
25
|
+
|
26
|
+
def example_count
|
27
|
+
@summary_notification.examples.count
|
28
|
+
end
|
29
|
+
|
30
|
+
def failure_count
|
31
|
+
@summary_notification.failed_examples.count
|
32
|
+
end
|
33
|
+
|
34
|
+
def duration
|
35
|
+
@summary_notification.duration
|
36
|
+
end
|
37
|
+
|
38
|
+
def examples
|
39
|
+
@examples_notification.notifications
|
40
|
+
end
|
41
|
+
|
42
|
+
def result_of(notification)
|
43
|
+
notification.example.execution_result.status
|
44
|
+
end
|
45
|
+
|
46
|
+
def example_group_file_path_for(notification)
|
47
|
+
notification.example.example_group.file_path
|
48
|
+
end
|
49
|
+
|
50
|
+
def classname_for(notification)
|
51
|
+
fp = example_group_file_path_for(notification)
|
52
|
+
fp.sub(%r{\.[^/]*\Z}, "").gsub("/", ".").gsub(%r{\A\.+|\.+\Z}, "")
|
53
|
+
end
|
54
|
+
|
55
|
+
def duration_for(notification)
|
56
|
+
notification.example.execution_result.run_time
|
57
|
+
end
|
58
|
+
|
59
|
+
def description_for(notification)
|
60
|
+
notification.example.full_description
|
61
|
+
end
|
62
|
+
|
63
|
+
def exception_for(notification)
|
64
|
+
notification.example.execution_result.exception
|
65
|
+
end
|
66
|
+
|
67
|
+
def formatted_backtrace_for(notification)
|
68
|
+
notification.formatted_backtrace
|
69
|
+
end
|
70
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec_junit_formatter_jenkins
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Touseef Liaqat
|
@@ -11,60 +11,74 @@ cert_chain: []
|
|
11
11
|
date: 2016-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: rspec
|
14
|
+
name: rspec-core
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2'
|
20
|
+
- - "<"
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
22
|
+
version: '4'
|
23
|
+
- - "!="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 2.12.0
|
20
26
|
type: :runtime
|
21
27
|
prerelease: false
|
22
28
|
version_requirements: !ruby/object:Gem::Requirement
|
23
29
|
requirements:
|
24
|
-
- - "
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2'
|
33
|
+
- - "<"
|
25
34
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
35
|
+
version: '4'
|
36
|
+
- - "!="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 2.12.0
|
27
39
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
40
|
+
name: builder
|
29
41
|
requirement: !ruby/object:Gem::Requirement
|
30
42
|
requirements:
|
31
|
-
- - "
|
43
|
+
- - "<"
|
32
44
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
45
|
+
version: '4'
|
34
46
|
type: :runtime
|
35
47
|
prerelease: false
|
36
48
|
version_requirements: !ruby/object:Gem::Requirement
|
37
49
|
requirements:
|
38
|
-
- - "
|
50
|
+
- - "<"
|
39
51
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
52
|
+
version: '4'
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
54
|
+
name: nokogiri
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
44
56
|
requirements:
|
45
|
-
- - "
|
57
|
+
- - "~>"
|
46
58
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
-
type: :
|
59
|
+
version: '1.6'
|
60
|
+
type: :development
|
49
61
|
prerelease: false
|
50
62
|
version_requirements: !ruby/object:Gem::Requirement
|
51
63
|
requirements:
|
52
|
-
- - "
|
64
|
+
- - "~>"
|
53
65
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
-
description: RSpec results that Hudson can read. Code
|
66
|
+
version: '1.6'
|
67
|
+
description: RSpec results that Hudson can read. Code forked from github.com/sj26/rspec_junit_formatter
|
56
68
|
and modified for our use.
|
57
69
|
email: touseefliaqat@gmail.com
|
58
70
|
executables: []
|
59
71
|
extensions: []
|
60
72
|
extra_rdoc_files: []
|
61
73
|
files:
|
62
|
-
- lib/
|
74
|
+
- lib/rspec_junit_formatter/rspec2.rb
|
75
|
+
- lib/rspec_junit_formatter/rspec3.rb
|
63
76
|
- lib/rspec_junit_formatter.rb
|
64
77
|
- README.md
|
65
78
|
- LICENSE
|
66
79
|
homepage: http://github.com/tliaqat/rspec_junit_formatter_jenkins
|
67
|
-
licenses:
|
80
|
+
licenses:
|
81
|
+
- MIT
|
68
82
|
metadata: {}
|
69
83
|
post_install_message:
|
70
84
|
rdoc_options: []
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'time'
|
2
|
-
|
3
|
-
# Dumps rspec results as a JUnit XML file.
|
4
|
-
# Based on XML schema: http://windyroad.org/dl/Open%20Source/JUnit.xsd
|
5
|
-
class RSpec::Core::Formatters::JUnitFormatter < RSpec::Core::Formatters::BaseFormatter
|
6
|
-
def xml
|
7
|
-
@xml ||= Builder::XmlMarkup.new :target => output, :indent => 2
|
8
|
-
end
|
9
|
-
|
10
|
-
def start example_count
|
11
|
-
@start = Time.now
|
12
|
-
super
|
13
|
-
end
|
14
|
-
|
15
|
-
def dump_summary duration, example_count, failure_count, pending_count
|
16
|
-
super
|
17
|
-
|
18
|
-
xml.instruct!
|
19
|
-
xml.testsuite :tests => example_count, :failures => failure_count, :errors => 0, :time => '%.6f' % duration, :timestamp => @start.iso8601 do
|
20
|
-
xml.properties
|
21
|
-
examples.each do |example|
|
22
|
-
send :"dump_summary_example_#{example.execution_result[:status]}", example
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def xml_example example, &block
|
28
|
-
xml.testcase :classname => example_classname(example), :name => example.full_description, :time => '%.6f' % example.execution_result[:run_time], &block
|
29
|
-
end
|
30
|
-
|
31
|
-
def dump_summary_example_passed example
|
32
|
-
xml_example example
|
33
|
-
end
|
34
|
-
|
35
|
-
def dump_summary_example_pending example
|
36
|
-
xml_example example do
|
37
|
-
xml.skipped
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def dump_summary_example_failed example
|
42
|
-
exception = example.execution_result[:exception]
|
43
|
-
backtrace = format_backtrace exception.backtrace, example
|
44
|
-
|
45
|
-
xml_example example do
|
46
|
-
xml.error message: exception.to_s, type: exception.class.name do
|
47
|
-
xml.text! "#{exception.message.encode(:xml => :text)}\n#{backtrace.join.encode(:xml => :text)}"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def example_classname example
|
53
|
-
example.file_path.sub(%r{\.[^/]*\Z}, "").gsub("/", ".").gsub(%r{\A\.+|\.+\Z}, "")
|
54
|
-
end
|
55
|
-
end
|