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

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>)


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

def errors
  @errors
end

#failuresArray<Ox::Element>

An array of XML elements that represent failed tests.

Returns:

  • (Array<Ox::Element>)


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

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.

Returns:

  • (Array<Symbol>)


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

def headers
  @headers
end

#passesArray<Ox::Element>

An array of XML elements that represent passed tests.

Returns:

  • (Array<Ox::Element>)


56
57
58
# File 'lib/junit/plugin.rb', line 56

def passes
  @passes
end

#show_skipped_testsBool

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

Returns:

  • (Bool)


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

def show_skipped_tests
  @show_skipped_tests
end

#skippedArray<Ox::Element>

An array of XML elements that represent skipped tests.

Returns:

  • (Array<Ox::Element>)


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

def skipped
  @skipped
end

#testsArray<Ox::Element>

All the tests for introspection

Returns:

  • (Array<Ox::Element>)


51
52
53
# File 'lib/junit/plugin.rb', line 51

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



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/junit/plugin.rb', line 87

def parse(file)
  require 'ox'
  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' }

  @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.



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 128

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

  unless failures.empty? && errors.empty?
    fail('Tests have failed, see below for more information.', sticky: false)
    message = "### Tests: \n\n"

    tests = (failures + errors)
    keys = headers || tests.first.attributes.keys
    attributes = keys.map(&:to_s).map(&:capitalize)

    # Create the headers
    message << attributes.join(' | ') + "|\n"
    message << attributes.map { |_| '---' }.join(' | ') + "|\n"

    # Map out the keys to the tests
    tests.each do |test|
      row_values = keys.map { |key| test.attributes[key] }.map { |v| auto_link(v) }
      message << row_values.join(' | ') + "|\n"
    end

    markdown message
  end
end