Class: Danger::DangerJunit

Inherits:
Plugin
  • Object
show all
Defined in:
lib/junit/plugin.rb

Overview

Report, or inspect any JUnit XML formatted test suite report.

Testing frameworks have standardized on the JUnit XML format for reporting results, this means that projects using Rspec, Jasmine, Mocha, XCTest and more - can all use the same Danger error reporting. Perfect.

You can see some examples on [this page from Circle CI](circleci.com/docs/test-metadata/) and on this [project’s README](github.com/orta/danger-junit.git) about how you can add JUnit XML output for your testing projects.

Examples:

Parse the XML file, and let the plugin do your reporting


junit.parse "/path/to/output.xml"
junit.report

Parse multiple XML files by passing multiple file names


junit.parse_files "/path/to/integration-tests.xml", "/path/to/unit-tests.xml"
junit.report

Parse multiple XML files by passing an array

result_files = %w(/path/to/integration-tests.xml /path/to/unit-tests.xml)
junit.parse_files result_files
junit.report

Let the plugin parse the XML file, and report yourself


junit.parse "/path/to/output.xml"
fail("Tests failed") unless junit.failures.empty?

Warn on a report about skipped tests


junit.parse "/path/to/output.xml"
junit.show_skipped_tests = true
junit.report

Only show specific parts of your results


junit.parse "/path/to/output.xml"
junit.headers = [:name, :file]
junit.report

Only show specific parts of your results


junit.parse "/path/to/output.xml"
all_test = junit.tests.map(&:attributes)
slowest_test = sort_by { |attributes| attributes[:time].to_f }.last
message "#{slowest_test[:time]} took #{slowest_test[:time]} seconds"

See Also:

  • orta/danger-junit
  • danger/danger
  • artsy/eigen

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#errorsArray<Ox::Element>

An array of XML elements that represent passed tests.

Returns:

  • (Array<Ox::Element>)


76
77
78
# File 'lib/junit/plugin.rb', line 76

def errors
  @errors
end

#failuresArray<Ox::Element>

An array of XML elements that represent failed tests.

Returns:

  • (Array<Ox::Element>)


71
72
73
# File 'lib/junit/plugin.rb', line 71

def failures
  @failures
end

#headersArray<Symbol>

An array of symbols that become the columns of your tests, if ‘nil`, the default, it will be all of the attributes for a single parse or all of the common attributes between multiple files

Returns:

  • (Array<Symbol>)


93
94
95
# File 'lib/junit/plugin.rb', line 93

def headers
  @headers
end

#passesArray<Ox::Element>

An array of XML elements that represent passed tests.

Returns:

  • (Array<Ox::Element>)


66
67
68
# File 'lib/junit/plugin.rb', line 66

def passes
  @passes
end

#show_skipped_testsBool

An attribute to make the plugin show a warning on skipped tests.

Returns:

  • (Bool)


86
87
88
# File 'lib/junit/plugin.rb', line 86

def show_skipped_tests
  @show_skipped_tests
end

#skippedArray<Ox::Element>

An array of XML elements that represent skipped tests.

Returns:

  • (Array<Ox::Element>)


81
82
83
# File 'lib/junit/plugin.rb', line 81

def skipped
  @skipped
end

#skipped_headersArray<Symbol>

An array of symbols that become the columns of your skipped tests, if ‘nil`, the default, it will be all of the attributes for a single parse or all of the common attributes between multiple files

Returns:

  • (Array<Symbol>)


100
101
102
# File 'lib/junit/plugin.rb', line 100

def skipped_headers
  @skipped_headers
end

#testsArray<Ox::Element>

All the tests for introspection

Returns:

  • (Array<Ox::Element>)


61
62
63
# File 'lib/junit/plugin.rb', line 61

def tests
  @tests
end

Instance Method Details

#parse(file) ⇒ void

This method returns an undefined value.

Parses an XML file, which fills all the attributes, will ‘raise` for errors



105
106
107
# File 'lib/junit/plugin.rb', line 105

def parse(file)
  parse_files(file)
end

#parse_files(*files) ⇒ void

This method returns an undefined value.

Parses multiple XML files, which fills all the attributes, will ‘raise` for errors



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/junit/plugin.rb', line 112

def parse_files(*files)
  require 'ox'
  @tests = []
  failed_tests = []

  Array(files).flatten.each do |file|
    raise "No JUnit file was found at #{file}" unless File.exist? file

    xml_string = File.read(file)
    doc = Ox.parse(xml_string)

    suite_root = doc.nodes.first.value == 'testsuites' ? doc.nodes.first : doc
    @tests += suite_root.nodes.map(&:nodes).flatten.select { |node| node.kind_of?(Ox::Element) && node.value == 'testcase' }

    failed_suites = suite_root.nodes.select { |suite| suite[:failures].to_i > 0 || suite[:errors].to_i > 0 }
    failed_tests += failed_suites.map(&:nodes).flatten.select { |node| node.kind_of?(Ox::Element) && node.value == 'testcase' }
  end

  @failures = failed_tests.select do |test|
    test.nodes.count > 0
  end.select do |test|
    node = test.nodes.first
    node.kind_of?(Ox::Element) && node.value == 'failure'
  end

  @errors = failed_tests.select do |test| 
    test.nodes.count > 0
  end.select do |test| 
    node = test.nodes.first
    node.kind_of?(Ox::Element) && node.value == 'error'
  end

  @skipped = tests.select do |test| 
    test.nodes.count > 0
  end.select do |test| 
    node = test.nodes.first
    node.kind_of?(Ox::Element) && node.value == 'skipped'
  end

  @passes = tests - @failures - @errors - @skipped
end

#reportvoid

This method returns an undefined value.

Causes a build fail if there are test failures, and outputs a markdown table of the results.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/junit/plugin.rb', line 158

def report
  return if failures.nil? # because danger calls `report` before loading a file
  if show_skipped_tests && skipped.count > 0
    warn("Skipped #{skipped.count} tests.")

    message = "### Skipped: \n\n"
    message << get_report_content(skipped, skipped_headers)
    markdown message

  end

  unless failures.empty? && errors.empty?
    fail('Tests have failed, see below for more information.', sticky: false)

    message = "### Tests: \n\n"
    tests = (failures + errors)
    message << get_report_content(tests, headers)
    markdown message
  end
end