Class: Fastlane::Actions::CollateJunitReportsAction

Inherits:
Action
  • Object
show all
Defined in:
lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb

Documentation collapse

Class Method Summary collapse

Class Method Details

.attribute_sum_string(node1, node2, attribute) ⇒ Object



74
75
76
77
78
# File 'lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb', line 74

def self.attribute_sum_string(node1, node2, attribute)
  value1 = node1.attributes[attribute].to_i
  value2 = node2.attributes[attribute].to_i
  (value1 + value2).to_s
end

.authorsObject



126
127
128
# File 'lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb', line 126

def self.authors
  ["lyndsey-ferguson/@lyndseydf"]
end

.available_optionsObject



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb', line 100

def self.available_options
  [
    FastlaneCore::ConfigItem.new(
      key: :reports,
      env_name: 'COLLATE_JUNIT_REPORTS_REPORTS',
      description: 'An array of junit reports to collate. The first report is used as the base into which other reports are merged in',
      optional: false,
      type: Array,
      verify_block: proc do |reports|
        UI.user_error!('No junit report files found') if reports.empty?
        reports.each do |report|
          UI.user_error!("Error: junit report not found: '#{report}'") unless File.exist?(report)
        end
      end
    ),
    FastlaneCore::ConfigItem.new(
      key: :collated_report,
      env_name: 'COLLATE_JUNIT_REPORTS_COLLATED_REPORT',
      description: 'The final junit report file where all testcases will be merged into',
      optional: true,
      default_value: 'result.xml',
      type: String
    )
  ]
end

.descriptionObject



84
85
86
# File 'lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb', line 84

def self.description
  "Combines and combines tests from multiple junit report files"
end

.detailsObject



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb', line 88

def self.details
  "The first junit report is used as the base report. Testcases " \
  "from other reports are added if they do not already exist, or " \
  "if the testcases already exist, they are replaced." \
  "" \
  "This is done because it is assumed that fragile tests, when " \
  "re-run will often succeed due to less interference from other " \
  "tests and the subsequent junit reports will have more passed tests." \
  "" \
  "Inspired by Derek Yang's fastlane-plugin-merge_junit_report"
end

.is_supported?(platform) ⇒ Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb', line 130

def self.is_supported?(platform)
  platform == :ios
end

.run(params) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb', line 4

def self.run(params)
  report_filepaths = params[:reports]
  if report_filepaths.size == 1
    FileUtils.cp(report_filepaths[0], params[:collated_report])
  else
    reports = report_filepaths.map { |report_filepath| REXML::Document.new(File.new(report_filepath)) }

    # copy any missing testsuites
    target_report = reports.shift
    reports.each do |report|
      report.elements.each('//testsuite') do |testsuite|
        testsuite_name = testsuite.attributes['name']

        target_testsuite = REXML::XPath.first(target_report, "//testsuite[@name='#{testsuite_name}']")
        if target_testsuite
          testsuite.elements.each('testcase') do |testcase|
            classname = testcase.attributes['classname']
            name = testcase.attributes['name']
            target_testcase = REXML::XPath.first(target_testsuite, "testcase[@name='#{name}' and @classname='#{classname}']")
            # Replace target_testcase with testcase
            if target_testcase
              target_testcase.parent.insert_after(target_testcase, testcase)
              target_testcase.parent.delete_element(target_testcase)
            else
              target_testsuite << testcase
            end
          end
        else
          testable = REXML::XPath.first(target_report, "//testsuites")
          testable << testsuite
        end
      end
    end
    target_report.elements.each('//testsuite') do |testsuite|
      update_testsuite_counts(testsuite)
    end
    testable = REXML::XPath.first(target_report, 'testsuites')
    update_testable_counts(testable)

    FileUtils.mkdir_p(File.dirname(params[:collated_report]))
    File.open(params[:collated_report], 'w') do |f|
      target_report.write(f, 2)
    end
  end
end

.update_testable_counts(testable) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb', line 50

def self.update_testable_counts(testable)
  testsuites = REXML::XPath.match(testable, 'testsuite')
  test_count = 0
  failure_count = 0
  testsuites.each do |testsuite|
    test_count += testsuite.attributes['tests'].to_i
    failure_count += testsuite.attributes['failures'].to_i
  end
  testable.attributes['tests'] = test_count.to_s
  testable.attributes['failures'] = failure_count.to_s
end

.update_testsuite_counts(testsuite) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb', line 62

def self.update_testsuite_counts(testsuite)
  testcases = REXML::XPath.match(testsuite, 'testcase')
  testsuite.attributes['tests'] = testcases.size.to_s
  failure_count = testcases.reduce(0) do |count, testcase|
    if REXML::XPath.first(testcase, 'failure')
      count += 1
    end
    count
  end
  testsuite.attributes['failures'] = failure_count.to_s
end