junit_report_generator 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +9 -0
  5. data/README.md +69 -0
  6. data/Rakefile +13 -0
  7. data/junit_report_generator.gemspec +22 -0
  8. data/lib/junit_report_generator.rb +5 -0
  9. data/lib/junit_report_generator/containable.rb +19 -0
  10. data/lib/junit_report_generator/elementary.rb +30 -0
  11. data/lib/junit_report_generator/elements/element.rb +24 -0
  12. data/lib/junit_report_generator/elements/error.rb +11 -0
  13. data/lib/junit_report_generator/elements/failure.rb +11 -0
  14. data/lib/junit_report_generator/elements/properties.rb +17 -0
  15. data/lib/junit_report_generator/elements/property.rb +17 -0
  16. data/lib/junit_report_generator/elements/skipped.rb +11 -0
  17. data/lib/junit_report_generator/elements/system_err.rb +11 -0
  18. data/lib/junit_report_generator/elements/system_out.rb +11 -0
  19. data/lib/junit_report_generator/elements/test_case.rb +19 -0
  20. data/lib/junit_report_generator/elements/test_suite.rb +40 -0
  21. data/lib/junit_report_generator/elements/test_suites.rb +33 -0
  22. data/lib/junit_report_generator/generator.rb +27 -0
  23. data/lib/junit_report_generator/report.rb +24 -0
  24. data/test/helper.rb +8 -0
  25. data/test/test_containable.rb +45 -0
  26. data/test/test_element.rb +49 -0
  27. data/test/test_elementary.rb +43 -0
  28. data/test/test_error.rb +7 -0
  29. data/test/test_failure.rb +7 -0
  30. data/test/test_generator.rb +43 -0
  31. data/test/test_properties.rb +12 -0
  32. data/test/test_property.rb +12 -0
  33. data/test/test_report.rb +24 -0
  34. data/test/test_skipped.rb +7 -0
  35. data/test/test_system_err.rb +7 -0
  36. data/test/test_system_out.rb +7 -0
  37. data/test/test_test_case.rb +14 -0
  38. data/test/test_test_suite.rb +95 -0
  39. data/test/test_test_suites.rb +43 -0
  40. metadata +156 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ac539b6d06cc043c568be60e360c3380e217ea0b
4
+ data.tar.gz: 82dff12242140aa88ad19cc01003c7122f57c24d
5
+ SHA512:
6
+ metadata.gz: 0ad2f7b2038c60a402d982acff6f52d46c4887cab9291d4ad3b78e1d9215b1cdf456b27b759ae9ece022198ba6e548fd452f3b0b2c1ec303b15ec7a48821bcd3
7
+ data.tar.gz: 8e1303686bc794483617c409f9ad02a777d39bb4e05b7a7439066fe6861af1614b7dc3b4fc8c9be456ee7c0cd1d4fb6a2ad2afecb22cdbb279a07b5df193676b
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ *.gem
3
+ coverage/
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.0
5
+ - 2.2.0
6
+ - ruby-head
7
+ env:
8
+ - CODECLIMATE_REPO_TOKEN="3124e4d5ad973c852dccbc34eb6bd3eb93ca3ab83f1cdcf1b6a56350c8388450"
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'nokogiri'
4
+
5
+ group :test do
6
+ gem 'rake'
7
+ gem 'minitest'
8
+ gem 'codeclimate-test-reporter'
9
+ end
@@ -0,0 +1,69 @@
1
+ # JunitReportGenerator
2
+
3
+ [![Build Status](https://travis-ci.org/thyrlian/JunitReportGenerator.svg?branch=master)](https://travis-ci.org/thyrlian/JunitReportGenerator)
4
+ [![Code Climate](https://codeclimate.com/github/thyrlian/JunitReportGenerator/badges/gpa.svg)](https://codeclimate.com/github/thyrlian/JunitReportGenerator)
5
+ [![Test Coverage](https://codeclimate.com/github/thyrlian/JunitReportGenerator/badges/coverage.svg)](https://codeclimate.com/github/thyrlian/JunitReportGenerator/coverage)
6
+
7
+ Easy and flexible solution to generating JUnit test result report from any format of data.
8
+
9
+ ## Usage
10
+ Install the library
11
+ ```shell
12
+ gem install junit_report_generator
13
+ ```
14
+
15
+ Example code snippets
16
+ ```ruby
17
+ require 'junit_report_generator'
18
+
19
+ include JunitReportGenerator
20
+
21
+ test_suite_1 = TestSuite.create('Test Suite 1')
22
+ # you can add all at once
23
+ test_suite_1.add(TestCase.create('Test Case'), TestCase.create('Test Case'))
24
+
25
+ test_suite_2 = TestSuite.create('Test Suite 2')
26
+ # or chaining add methods one after another
27
+ test_suite_2.add(TestCase.create('Test Case')).add(TestCase.create('Test Case'))
28
+
29
+ test_suites = TestSuites.create.add(test_suite_1, test_suite_2)
30
+
31
+ Report.on(test_suites).publish('[path_of_output_xml_test_results]')
32
+ ```
33
+
34
+ ## Syntax
35
+ * Add sub-elements to test case / suite(s)
36
+ ```ruby
37
+ TestCase.create('test').add(sub_element_1, sub_element_2).add(sub_element_3)
38
+ ```
39
+ * Add attribute(s) to any xml element (attribute methods are dynamically defined)
40
+ ```ruby
41
+ TestCase.create('test').attribute('value').whatever_you_want('foo')
42
+ ```
43
+ * Test case result format: Pass, Failure, Error, Skipped.
44
+ ```ruby
45
+ TestCase.create('test') # Pass: no sub-element
46
+ TestCase.create('test').add(Failure.create) # Failure
47
+ TestCase.create('test').add(Error.create) # Error
48
+ TestCase.create('test').add(Skipped.create) # Skipped
49
+ ```
50
+
51
+ ## Notes
52
+ The statistics attributes in testsuite(s) are not really used by Jenkins (they are optional), in fact, Jenkins is doing the math by itself via counting the numbers from each testcase.
53
+ ```xml
54
+ <!-- these attributes are optional -->
55
+ <testsuite name="foobar" tests="10" errors="3" failures="2" skipped="1" time="12.34">
56
+ ```
57
+
58
+ ## Reference
59
+ [JUnit test reports specification](https://svn.jenkins-ci.org/trunk/hudson/dtkit/dtkit-format/dtkit-junit-model/src/main/resources/com/thalesgroup/dtkit/junit/model/xsd/)
60
+
61
+ ## License
62
+
63
+ Copyright (c) 2015 Jing Li
64
+
65
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
66
+
67
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
68
+
69
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), *%w[lib])))
2
+ require 'junit_report_generator'
3
+ require 'rake/testtask'
4
+
5
+ ENV['CODECLIMATE_REPO_TOKEN'] = '3124e4d5ad973c852dccbc34eb6bd3eb93ca3ab83f1cdcf1b6a56350c8388450'
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs << 'test'
9
+ t.test_files = FileList['test/test*.rb']
10
+ end
11
+
12
+ desc 'Run tests'
13
+ task :default => :test
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ $: << File.expand_path('../lib', __FILE__)
4
+ require 'junit_report_generator'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'junit_report_generator'
8
+ s.version = JunitReportGenerator::VERSION
9
+ s.license = 'MIT'
10
+ s.date = '2015-08-11'
11
+ s.summary = 'Generating JUnit test report easily from any source.'
12
+ s.description = 'Generating JUnit test result report (xml) from any format of data by super easy and flexible syntax. Most of the CIs (Continuous Integration) can aggregate JUnit style reports with zero effort.'
13
+ s.authors = ['Jing Li']
14
+ s.email = ['thyrlian@gmail.com']
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.homepage = 'https://github.com/thyrlian/JunitReportGenerator'
18
+ s.add_dependency 'nokogiri', '~> 1.6'
19
+ s.add_development_dependency 'rake', '~> 10.4'
20
+ s.add_development_dependency 'minitest', '~> 5.7'
21
+ s.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.7'
22
+ end
@@ -0,0 +1,5 @@
1
+ Dir.glob(File.expand_path(File.dirname(__FILE__)) + '/junit_report_generator/**/*.rb').each { |file| require file }
2
+
3
+ module JunitReportGenerator
4
+ VERSION = '1.0.0'
5
+ end
@@ -0,0 +1,19 @@
1
+ module JunitReportGenerator
2
+ module Containable
3
+ attr_reader :sub_elements
4
+
5
+ def register(&blk)
6
+ @sub_elements = []
7
+ @blk = blk
8
+ end
9
+
10
+ def add(*sub_elements)
11
+ @sub_elements ||= []
12
+ @sub_elements.concat(sub_elements)
13
+ @blk.call(sub_elements) if defined?(@blk) && @blk
14
+ self
15
+ end
16
+
17
+ private :register
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ module JunitReportGenerator
2
+ module Elementary
3
+ attr_reader :attributes
4
+
5
+ def assemble_attributes(*attrs)
6
+ attributes = {}
7
+ attrs.each do |attr|
8
+ attr = attr.to_sym
9
+ attributes[attr] = instance_variable_get("@#{attr.id2name}")
10
+ end
11
+ instance_variable_set(:@attributes, attributes)
12
+ end
13
+
14
+ def update_attributes(*attrs)
15
+ attrs.each do |attr|
16
+ attr = attr.to_sym
17
+ instance_variable_get(:@attributes)[attr] = instance_variable_get("@#{attr.id2name}")
18
+ end
19
+ end
20
+
21
+ def method_missing(method, *args)
22
+ instance_variable_get(:@attributes)[method] = args.first
23
+ self.class.send(:define_method, method) do |value|
24
+ instance_variable_get(:@attributes)[method] = value
25
+ self
26
+ end
27
+ self
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ require_relative '../elementary'
2
+ require_relative '../containable'
3
+
4
+ module JunitReportGenerator
5
+ class Element
6
+ include Elementary
7
+
8
+ class << self
9
+ def create(*args)
10
+ new(*args)
11
+ end
12
+
13
+ def include_containable
14
+ include Containable
15
+ end
16
+
17
+ def xml_tag_name
18
+ raise(NotImplementedError, "Abstract method [#{__method__}] is called, please implement", caller)
19
+ end
20
+ end
21
+
22
+ private_class_method :new, :include_containable
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'element'
2
+
3
+ module JunitReportGenerator
4
+ class Error < Element
5
+ class << self
6
+ def xml_tag_name
7
+ 'error'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'element'
2
+
3
+ module JunitReportGenerator
4
+ class Failure < Element
5
+ class << self
6
+ def xml_tag_name
7
+ 'failure'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'element'
2
+
3
+ module JunitReportGenerator
4
+ class Properties < Element
5
+ include_containable
6
+
7
+ def initialize
8
+ register
9
+ end
10
+
11
+ class << self
12
+ def xml_tag_name
13
+ 'properties'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'element'
2
+
3
+ module JunitReportGenerator
4
+ class Property < Element
5
+ def initialize(name, value)
6
+ @name = name
7
+ @value = value
8
+ assemble_attributes(:name, :value)
9
+ end
10
+
11
+ class << self
12
+ def xml_tag_name
13
+ 'property'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'element'
2
+
3
+ module JunitReportGenerator
4
+ class Skipped < Element
5
+ class << self
6
+ def xml_tag_name
7
+ 'skipped'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'element'
2
+
3
+ module JunitReportGenerator
4
+ class SystemErr < Element
5
+ class << self
6
+ def xml_tag_name
7
+ 'system-err'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'element'
2
+
3
+ module JunitReportGenerator
4
+ class SystemOut < Element
5
+ class << self
6
+ def xml_tag_name
7
+ 'system-out'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'element'
2
+
3
+ module JunitReportGenerator
4
+ class TestCase < Element
5
+ include_containable
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ assemble_attributes(:name)
10
+ register
11
+ end
12
+
13
+ class << self
14
+ def xml_tag_name
15
+ 'testcase'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'element'
2
+ require_relative 'test_case'
3
+ require_relative 'error'
4
+ require_relative 'failure'
5
+ require_relative 'skipped'
6
+
7
+ module JunitReportGenerator
8
+ class TestSuite < Element
9
+ include_containable
10
+
11
+ def initialize(name)
12
+ @name = name
13
+ @tests = 0
14
+ @errors = 0
15
+ @failures = 0
16
+ @skipped = 0
17
+ @time = 0
18
+ assemble_attributes(:name, :tests, :errors, :failures, :skipped, :time)
19
+ register do |sub_elements|
20
+ sub_elements.each do |sub_element|
21
+ if sub_element.is_a?(TestCase)
22
+ @tests += 1
23
+ @time += sub_element.attributes.fetch(:time, 0).to_f
24
+ class_types = sub_element.sub_elements.map { |x| x.class }
25
+ @errors += 1 if class_types.include?(Error)
26
+ @failures += 1 if class_types.include?(Failure)
27
+ @skipped += 1 if class_types.include?(Skipped)
28
+ end
29
+ end
30
+ update_attributes(:tests, :errors, :failures, :skipped, :time)
31
+ end
32
+ end
33
+
34
+ class << self
35
+ def xml_tag_name
36
+ 'testsuite'
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'element'
2
+
3
+ module JunitReportGenerator
4
+ class TestSuites < Element
5
+ include_containable
6
+
7
+ def initialize
8
+ @tests = 0
9
+ @errors = 0
10
+ @failures = 0
11
+ @disabled = 0
12
+ @time = 0
13
+ assemble_attributes(:tests, :errors, :failures, :disabled, :time)
14
+ register do |sub_elements|
15
+ sub_elements.each do |sub_element|
16
+ attributes = sub_element.attributes
17
+ @tests += attributes.fetch(:tests, 0).to_i
18
+ @errors += attributes.fetch(:errors, 0).to_i
19
+ @failures += attributes.fetch(:failures, 0).to_i
20
+ @disabled += attributes.fetch(:disabled, 0).to_i
21
+ @time += attributes.fetch(:time, 0).to_f
22
+ end
23
+ update_attributes(:tests, :errors, :failures, :disabled, :time)
24
+ end
25
+ end
26
+
27
+ class << self
28
+ def xml_tag_name
29
+ 'testsuites'
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ require 'nokogiri'
2
+
3
+ module JunitReportGenerator
4
+ class Generator
5
+ class << self
6
+ def produce(test_suites)
7
+ builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
8
+ build_tags(xml, test_suites)
9
+ end
10
+ builder.to_xml
11
+ end
12
+
13
+ def build_tags(xml, element)
14
+ tag_name = element.class.xml_tag_name
15
+ xml.send(tag_name, element.attributes) do
16
+ if element.respond_to?(:sub_elements)
17
+ element.sub_elements.each do |sub_element|
18
+ build_tags(xml, sub_element)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ private_class_method :new, :build_tags
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ require_relative '../junit_report_generator'
2
+
3
+ module JunitReportGenerator
4
+ class Report
5
+ def initialize(test_suites)
6
+ @test_suites = test_suites
7
+ end
8
+
9
+ class << self
10
+ def on(test_suites)
11
+ new(test_suites)
12
+ end
13
+ end
14
+
15
+ def publish(file)
16
+ xml = Generator.produce(@test_suites)
17
+ File.open(file, 'w') do |f|
18
+ f.puts xml
19
+ end
20
+ end
21
+
22
+ private_class_method :new
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
+
4
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), *%w[.. lib junit_report_generator])))
5
+ require 'junit_report_generator'
6
+ require 'minitest/autorun'
7
+
8
+ include JunitReportGenerator
@@ -0,0 +1,45 @@
1
+ require_relative 'helper'
2
+
3
+ class TestContainable < Minitest::Test
4
+ def setup
5
+ @klass_without_register = Class.new do
6
+ include Containable
7
+ end
8
+
9
+ @klass_with_register = Class.new do
10
+ include Containable
11
+
12
+ attr_reader :count
13
+
14
+ def initialize
15
+ @count = 0
16
+ register do |sub_elements|
17
+ @count += sub_elements.size
18
+ end
19
+ end
20
+ end
21
+
22
+ @object_without_register = @klass_without_register.new
23
+ @object_with_register = @klass_with_register.new
24
+
25
+ @sub_element_1 = MiniTest::Mock.new
26
+ @sub_element_2 = MiniTest::Mock.new
27
+ @sub_element_3 = MiniTest::Mock.new
28
+ end
29
+
30
+ def test_add_by_splatting_arguments
31
+ @object_without_register.add(@sub_element_1, @sub_element_2, @sub_element_3)
32
+ assert_equal(3, @object_without_register.sub_elements.size)
33
+ end
34
+
35
+ def test_add_by_chaining
36
+ @object_without_register.add(@sub_element_1).add(@sub_element_2)
37
+ assert_equal(2, @object_without_register.sub_elements.size)
38
+ end
39
+
40
+ def test_register_with_block
41
+ assert_equal(0, @object_with_register.count)
42
+ @object_with_register.add(@sub_element_1).add(@sub_element_2)
43
+ assert_equal(2, @object_with_register.count)
44
+ end
45
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'helper'
2
+
3
+ class TestElement < Minitest::Test
4
+ def setup
5
+ @klass = Class.new(Element) do
6
+ end
7
+
8
+ @klass_with_constructor = Class.new(Element) do
9
+ attr_reader :name, :value
10
+
11
+ def initialize(name, value)
12
+ @name = name
13
+ @value = value
14
+ end
15
+ end
16
+ end
17
+
18
+ def test_empty_constructor
19
+ @klass.create
20
+ end
21
+
22
+ def test_constructor_with_arguments
23
+ assert_raises ArgumentError do
24
+ @klass_with_constructor.create
25
+ end
26
+
27
+ object = @klass_with_constructor.create('AwesomeTest', 23)
28
+ assert_equal('AwesomeTest', object.name)
29
+ assert_equal(23, object.value)
30
+ end
31
+
32
+ def test_private_class_method_new
33
+ assert_raises NoMethodError do
34
+ @klass.new
35
+ end
36
+ end
37
+
38
+ def test_include_containable
39
+ assert(!@klass.ancestors.include?(JunitReportGenerator::Containable))
40
+ @klass.send(:include_containable)
41
+ assert(@klass.ancestors.include?(JunitReportGenerator::Containable))
42
+ end
43
+
44
+ def test_xml_tag_name
45
+ assert_raises NotImplementedError do
46
+ @klass.xml_tag_name
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,43 @@
1
+ require_relative 'helper'
2
+
3
+ class TestElementary < Minitest::Test
4
+ def setup
5
+ @klass = Class.new do
6
+ include Elementary
7
+
8
+ def initialize(name, value)
9
+ @name = name
10
+ @value = value
11
+ assemble_attributes(:name, :value)
12
+ end
13
+
14
+ def change(value)
15
+ @value = value
16
+ update_attributes(:value)
17
+ end
18
+ end
19
+
20
+ @object = @klass.new('foobar', 88)
21
+ end
22
+
23
+ def test_assemble_attributes
24
+ assert_equal({:name => 'foobar', :value => 88}, @object.attributes)
25
+ end
26
+
27
+ def test_update_attributes
28
+ @object.change(1024)
29
+ assert_equal({:name => 'foobar', :value => 1024}, @object.attributes)
30
+ end
31
+
32
+ def test_method_missing_should_add_optional_attribute
33
+ @object.status('Unknown')
34
+ assert_equal({:name => 'foobar', :value => 88, :status => 'Unknown'}, @object.attributes)
35
+ end
36
+
37
+ def test_method_missing_should_cache_optional_attribute_to_method
38
+ assert(!@klass.instance_methods.include?(:status))
39
+ @object.status('Unknown')
40
+ assert(@klass.instance_methods.include?(:status))
41
+ assert_equal({:name => 'foobar', :value => 88, :status => 'Unknown'}, @object.attributes)
42
+ end
43
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'helper'
2
+
3
+ class TestError < Minitest::Test
4
+ def test_xml_tag_name
5
+ assert_equal('error', Error.xml_tag_name)
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'helper'
2
+
3
+ class TestFailure < Minitest::Test
4
+ def test_xml_tag_name
5
+ assert_equal('failure', Failure.xml_tag_name)
6
+ end
7
+ end
@@ -0,0 +1,43 @@
1
+ require_relative 'helper'
2
+
3
+ class TestGenerator < Minitest::Test
4
+ def test_produce
5
+ test_suites = TestSuites.create
6
+ test_suite = TestSuite.create('UI-Tests')
7
+ test_suite.add(TestCase.create('testHome').classname('HomeActivityTest').time('2.081'))
8
+ .add(TestCase.create('testLoginWithCorrectCredentials').classname('LoginActivityTest').time('7.472'))
9
+ .add(TestCase.create('testLoginWithWrongCredentials').classname('LoginActivityTest').time('6.691'))
10
+ test_suites.add(test_suite)
11
+ xml = Generator.produce(test_suites)
12
+ doc = Nokogiri::Slop(xml)
13
+
14
+ assert_equal(3, doc.testsuites.testsuite.testcase.size)
15
+ assert_equal('testLoginWithWrongCredentials', doc.testsuites.testsuite.testcase.last['name'])
16
+ assert_equal('LoginActivityTest', doc.testsuites.testsuite.testcase.last['classname'])
17
+ assert_equal('6.691', doc.testsuites.testsuite.testcase.last['time'])
18
+ end
19
+
20
+ def test_build_tags_without_recursion
21
+ xml = Nokogiri::XML::Builder.new do |xml|
22
+ Generator.send(:build_tags, xml, TestSuites.create)
23
+ end.to_xml
24
+
25
+ assert(Nokogiri::XML(xml).xpath('//testsuites').children.empty?)
26
+ end
27
+
28
+ def test_build_tags_with_sub_elements
29
+ test_suites = TestSuites.create
30
+ test_suite = TestSuite.create('UI-Tests')
31
+ test_suite.add(TestCase.create('testHome').classname('HomeActivityTest').time('2.081'))
32
+ .add(TestCase.create('testLoginWithCorrectCredentials').classname('LoginActivityTest').time('7.472'))
33
+ .add(TestCase.create('testLoginWithWrongCredentials').classname('LoginActivityTest').time('6.691'))
34
+ test_suites.add(test_suite)
35
+
36
+ xml = Nokogiri::XML::Builder.new do |xml|
37
+ Generator.send(:build_tags, xml, test_suites)
38
+ end.to_xml
39
+
40
+ assert(!Nokogiri::XML(xml).xpath('//testsuites').children.empty?)
41
+ assert_equal(3, Nokogiri::XML(xml).xpath('//testcase').size)
42
+ end
43
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'helper'
2
+
3
+ class TestProperties < Minitest::Test
4
+ def test_create
5
+ properties = Properties.create
6
+ assert_equal([], properties.sub_elements)
7
+ end
8
+
9
+ def test_xml_tag_name
10
+ assert_equal('properties', Properties.xml_tag_name)
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'helper'
2
+
3
+ class TestProperty < Minitest::Test
4
+ def test_create
5
+ property = Property.create('os.vendor', 'Macrohard Corporation')
6
+ assert_equal({:name => 'os.vendor', :value => 'Macrohard Corporation'}, property.attributes)
7
+ end
8
+
9
+ def test_xml_tag_name
10
+ assert_equal('property', Property.xml_tag_name)
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'helper'
2
+
3
+ class TestReport < Minitest::Test
4
+ def setup
5
+ @test_suites = MiniTest::Mock.new
6
+ @report = Report.on(@test_suites)
7
+ @file = MiniTest::Mock.new
8
+ end
9
+
10
+ def test_on
11
+ @test_suites.expect(:==, true, [@test_suites])
12
+ assert_equal(@test_suites, @report.instance_variable_get(:@test_suites))
13
+ end
14
+
15
+ def test_publish
16
+ xml = 'Pseudo XML'
17
+ Generator.stub(:produce, xml) do
18
+ File.stub(:open, '', @file) do
19
+ @file.expect(:puts, '', [xml])
20
+ @report.publish(@file)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'helper'
2
+
3
+ class TestSkipped < Minitest::Test
4
+ def test_xml_tag_name
5
+ assert_equal('skipped', Skipped.xml_tag_name)
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'helper'
2
+
3
+ class TestSystemErr < Minitest::Test
4
+ def test_xml_tag_name
5
+ assert_equal('system-err', SystemErr.xml_tag_name)
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'helper'
2
+
3
+ class TestSystemOut < Minitest::Test
4
+ def test_xml_tag_name
5
+ assert_equal('system-out', SystemOut.xml_tag_name)
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'helper'
2
+
3
+ class TestTestCase < Minitest::Test
4
+ def test_create
5
+ test_case = TestCase.create('Awesome Test')
6
+ assert_equal('Awesome Test', test_case.instance_variable_get(:@name))
7
+ assert_equal({:name => 'Awesome Test'}, test_case.attributes)
8
+ assert_equal([], test_case.sub_elements)
9
+ end
10
+
11
+ def test_xml_tag_name
12
+ assert_equal('testcase', TestCase.xml_tag_name)
13
+ end
14
+ end
@@ -0,0 +1,95 @@
1
+ require_relative 'helper'
2
+
3
+ class TestTestSuite < Minitest::Test
4
+ def setup
5
+ @test_suite = TestSuite.create('Sonar')
6
+ @test_case_1 = MiniTest::Mock.new
7
+ @test_case_2 = MiniTest::Mock.new
8
+ @test_case_3 = MiniTest::Mock.new
9
+ @test_case_4 = MiniTest::Mock.new
10
+ @test_case_5 = MiniTest::Mock.new
11
+ @test_case_6 = MiniTest::Mock.new
12
+ @test_case_7 = MiniTest::Mock.new
13
+ @test_case_8 = MiniTest::Mock.new
14
+ end
15
+
16
+ def test_create
17
+ assert_equal('Sonar', @test_suite.instance_variable_get(:@name))
18
+ assert_equal('Sonar', @test_suite.attributes[:name])
19
+ assert_equal(0, @test_suite.attributes[:tests])
20
+ assert_equal([], @test_suite.sub_elements)
21
+ end
22
+
23
+ def test_empty_test_suite
24
+ assert_equal(0, @test_suite.instance_variable_get(:@tests))
25
+ end
26
+
27
+ def test_add_by_splatting_arguments
28
+ @test_case_1.expect(:is_a?, true, [TestCase])
29
+ @test_case_2.expect(:is_a?, true, [TestCase])
30
+ @test_case_3.expect(:is_a?, true, [TestCase])
31
+ @test_case_1.expect(:sub_elements, [])
32
+ @test_case_2.expect(:sub_elements, [])
33
+ @test_case_3.expect(:sub_elements, [])
34
+ @test_case_1.expect(:attributes, {})
35
+ @test_case_2.expect(:attributes, {})
36
+ @test_case_3.expect(:attributes, {})
37
+ @test_suite.add(@test_case_1, @test_case_2, @test_case_3)
38
+ assert_equal(3, @test_suite.instance_variable_get(:@tests))
39
+ end
40
+
41
+ def test_add_by_chaining
42
+ @test_case_1.expect(:is_a?, true, [TestCase])
43
+ @test_case_2.expect(:is_a?, true, [TestCase])
44
+ @test_case_1.expect(:sub_elements, [])
45
+ @test_case_2.expect(:sub_elements, [])
46
+ @test_case_1.expect(:attributes, {})
47
+ @test_case_2.expect(:attributes, {})
48
+ @test_suite.add(@test_case_1).add(@test_case_2)
49
+ assert_equal(2, @test_suite.instance_variable_get(:@tests))
50
+ end
51
+
52
+ def test_xml_tag_name
53
+ assert_equal('testsuite', TestSuite.xml_tag_name)
54
+ end
55
+
56
+ def test_register_block
57
+ sub_element = MiniTest::Mock.new
58
+
59
+ @test_case_1.expect(:is_a?, true, [TestCase])
60
+ @test_case_2.expect(:is_a?, true, [TestCase])
61
+ @test_case_3.expect(:is_a?, true, [TestCase])
62
+ @test_case_4.expect(:is_a?, true, [TestCase])
63
+ @test_case_5.expect(:is_a?, true, [TestCase])
64
+ @test_case_6.expect(:is_a?, true, [TestCase])
65
+ @test_case_7.expect(:is_a?, true, [TestCase])
66
+ @test_case_8.expect(:is_a?, true, [TestCase])
67
+ sub_element.expect(:is_a?, false, [TestCase])
68
+
69
+ @test_case_1.expect(:attributes, {:time => '200.36'})
70
+ @test_case_2.expect(:attributes, {:time => '1000.0'})
71
+ @test_case_3.expect(:attributes, {:time => 0.00080})
72
+ @test_case_4.expect(:attributes, {:time => '0.00009'})
73
+ @test_case_5.expect(:attributes, {:time => '30s'})
74
+ @test_case_6.expect(:attributes, {:time => '4.2'})
75
+ @test_case_7.expect(:attributes, {})
76
+ @test_case_8.expect(:attributes, {:time => '0.0070'})
77
+
78
+ @test_case_1.expect(:sub_elements, [Failure.create])
79
+ @test_case_2.expect(:sub_elements, [])
80
+ @test_case_3.expect(:sub_elements, [Properties.create, Error.create])
81
+ @test_case_4.expect(:sub_elements, [SystemOut.create])
82
+ @test_case_5.expect(:sub_elements, [SystemOut.create, SystemErr.create, Failure.create])
83
+ @test_case_6.expect(:sub_elements, [Skipped.create])
84
+ @test_case_7.expect(:sub_elements, [Failure.create])
85
+ @test_case_8.expect(:sub_elements, [Error.create, Properties.create])
86
+
87
+ @test_suite.add(@test_case_1, @test_case_2, @test_case_3, @test_case_4, @test_case_5, @test_case_6, @test_case_7, @test_case_8, sub_element)
88
+
89
+ assert_equal(8, @test_suite.attributes[:tests])
90
+ assert_equal(2, @test_suite.attributes[:errors])
91
+ assert_equal(3, @test_suite.attributes[:failures])
92
+ assert_equal(1, @test_suite.attributes[:skipped])
93
+ assert_in_delta(1234.56789, @test_suite.attributes[:time], 0.000001)
94
+ end
95
+ end
@@ -0,0 +1,43 @@
1
+ require_relative 'helper'
2
+
3
+ class TestTestSuites < Minitest::Test
4
+ def setup
5
+ @test_suite_1 = MiniTest::Mock.new
6
+ @test_suite_2 = MiniTest::Mock.new
7
+ @test_suite_3 = MiniTest::Mock.new
8
+ @test_suite_4 = MiniTest::Mock.new
9
+ @test_suite_5 = MiniTest::Mock.new
10
+ @test_suite_6 = MiniTest::Mock.new
11
+ @test_suite_7 = MiniTest::Mock.new
12
+ @test_suite_8 = MiniTest::Mock.new
13
+ end
14
+
15
+ def test_create
16
+ test_suites = TestSuites.create
17
+ assert_equal([], test_suites.sub_elements)
18
+ end
19
+
20
+ def test_xml_tag_name
21
+ assert_equal('testsuites', TestSuites.xml_tag_name)
22
+ end
23
+
24
+ def test_register_block
25
+ @test_suite_1.expect(:attributes, {:tests => 5, :failures => 1, :time => 60})
26
+ @test_suite_2.expect(:attributes, {})
27
+ @test_suite_3.expect(:attributes, {:tests => 0, :errors => 0, :failures => 0, :disabled => 0, :time => 0})
28
+ @test_suite_4.expect(:attributes, {:tests => 10, :errors => 2, :failures => 0, :disabled => 0, :time => 100})
29
+ @test_suite_5.expect(:attributes, {:tests => 5, :errors => 0, :failures => 0, :disabled => 2, :time => 50.078})
30
+ @test_suite_6.expect(:attributes, {:tests => 3, :errors => 1, :failures => 1, :disabled => 1, :time => 10.0009})
31
+ @test_suite_7.expect(:attributes, {:tests => 6, :errors => 2, :failures => 2, :time => 0})
32
+ @test_suite_8.expect(:attributes, {:tests => 1, :errors => 0, :failures => 0, :disabled => 0, :time => 4.6})
33
+
34
+ test_suites = TestSuites.create
35
+ test_suites.add(@test_suite_1, @test_suite_2, @test_suite_3, @test_suite_4, @test_suite_5, @test_suite_6, @test_suite_7, @test_suite_8)
36
+
37
+ assert_equal(30, test_suites.attributes[:tests])
38
+ assert_equal(5, test_suites.attributes[:errors])
39
+ assert_equal(4, test_suites.attributes[:failures])
40
+ assert_equal(3, test_suites.attributes[:disabled])
41
+ assert_in_delta(224.6789, test_suites.attributes[:time], 0.00001)
42
+ end
43
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: junit_report_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jing Li
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.4'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '5.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '5.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: codeclimate-test-reporter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.4.7
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.4.7
69
+ description: Generating JUnit test result report (xml) from any format of data by
70
+ super easy and flexible syntax. Most of the CIs (Continuous Integration) can aggregate
71
+ JUnit style reports with zero effort.
72
+ email:
73
+ - thyrlian@gmail.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - .gitignore
79
+ - .travis.yml
80
+ - Gemfile
81
+ - README.md
82
+ - Rakefile
83
+ - junit_report_generator.gemspec
84
+ - lib/junit_report_generator.rb
85
+ - lib/junit_report_generator/containable.rb
86
+ - lib/junit_report_generator/elementary.rb
87
+ - lib/junit_report_generator/elements/element.rb
88
+ - lib/junit_report_generator/elements/error.rb
89
+ - lib/junit_report_generator/elements/failure.rb
90
+ - lib/junit_report_generator/elements/properties.rb
91
+ - lib/junit_report_generator/elements/property.rb
92
+ - lib/junit_report_generator/elements/skipped.rb
93
+ - lib/junit_report_generator/elements/system_err.rb
94
+ - lib/junit_report_generator/elements/system_out.rb
95
+ - lib/junit_report_generator/elements/test_case.rb
96
+ - lib/junit_report_generator/elements/test_suite.rb
97
+ - lib/junit_report_generator/elements/test_suites.rb
98
+ - lib/junit_report_generator/generator.rb
99
+ - lib/junit_report_generator/report.rb
100
+ - test/helper.rb
101
+ - test/test_containable.rb
102
+ - test/test_element.rb
103
+ - test/test_elementary.rb
104
+ - test/test_error.rb
105
+ - test/test_failure.rb
106
+ - test/test_generator.rb
107
+ - test/test_properties.rb
108
+ - test/test_property.rb
109
+ - test/test_report.rb
110
+ - test/test_skipped.rb
111
+ - test/test_system_err.rb
112
+ - test/test_system_out.rb
113
+ - test/test_test_case.rb
114
+ - test/test_test_suite.rb
115
+ - test/test_test_suites.rb
116
+ homepage: https://github.com/thyrlian/JunitReportGenerator
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.4.3
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: Generating JUnit test report easily from any source.
140
+ test_files:
141
+ - test/helper.rb
142
+ - test/test_containable.rb
143
+ - test/test_element.rb
144
+ - test/test_elementary.rb
145
+ - test/test_error.rb
146
+ - test/test_failure.rb
147
+ - test/test_generator.rb
148
+ - test/test_properties.rb
149
+ - test/test_property.rb
150
+ - test/test_report.rb
151
+ - test/test_skipped.rb
152
+ - test/test_system_err.rb
153
+ - test/test_system_out.rb
154
+ - test/test_test_case.rb
155
+ - test/test_test_suite.rb
156
+ - test/test_test_suites.rb