Class: Fastlane::Actions::RescanFlakyTestsAction

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

Class Method Summary collapse

Class Method Details

.authorsObject



54
55
56
# File 'lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb', line 54

def self.authors
  ["Ichiko Moro"]
end

.available_optionsObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb', line 63

def self.available_options
  containing = FastlaneCore::Helper.fastlane_enabled_folder_path

  [
    FastlaneCore::ConfigItem.new(key: :report_file,
                                 env_name: 'RESCAN_REPORT_FILE',
                                 description: "JUnit report file path generated by scan, rescan target test cases extract from the file",
                                 type: String,
                                 default_value: File.join(containing, "test_output", "report.junit"),
                                 default_value_dynamic: true),
    FastlaneCore::ConfigItem.new(key: :output_directory,
                                 env_name: 'RESCAN_OUTPUT_DIRECTORY',
                                 description: "Each rescaned report and build log is saved in rescan_NN under the path",
                                 type: String,
                                 default_value: File.join(containing, "test_output"),
                                 default_value_dynamic: true,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :failed_test_limit,
                                 env_name: 'RESCAN_FAILED_TEST_LIMIT',
                                 description: "Stop rescan if faild test cases count is greater than this threshold. No limitation if this value is ZERO",
                                 type: Integer,
                                 default_value: 0,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :scan,
                                 description: "Parameters that are passed to the scan action",
                                 type: Hash,
                                 default_value: {},
                                 optional: true)
  ]
end

.descriptionObject



50
51
52
# File 'lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb', line 50

def self.description
  "Re-run `scan` action for each failed test case."
end

.detailsObject



58
59
60
61
# File 'lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb', line 58

def self.details
  "When you running UI tests (XCUITest, EarlGrey or others), sometime that failed with un clear reason. \n\
This plugin re-scan each failed test cases. And report result under `\#{output_directory}/rescan/NN`."
end

.example_codeObject



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
123
# File 'lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb', line 98

def self.example_code
  [
    '# shoud run `scan` before to get first test result.',
    'begin
      scan
    rescue
      rescan_flaky_tests
    end',
    '# use rescue block or `fail_build` option',
    'scan(fail_build: false)
    rescan_flaky_tests',
    '# recommend to pack scan options',
    'scan_options = {
      ...
    }
    begin
      scan(scan_options)
    rescue
      rescan_flaky_tests(
        scan_options.merge {
          report_file: "path/to/report.junit"
        }
      )
    end'
  ]
end

.is_supported?(platform) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb', line 94

def self.is_supported?(platform)
  [:ios, :mac].include?(platform)
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/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb', line 4

def self.run(params)
  first_report_path = params[:report_file]
  unless File.exist?(first_report_path)
    UI.user_error!("The report file '#{first_report_path}' is not found.")
  end

  test_cases = Helper::RescanFlakyTestsHelper.extract_failed_test_cases(first_report_path)
  if test_cases.nil?
    UI.user_error!("The report should be junit xml file.")
  end
  if test_cases.empty?
    UI.important("There is no test to retry.")
    return true
  end

  failed_test_limit = params[:failed_test_limit]
  if failed_test_limit > 0 && failed_test_limit < test_cases.count
    UI.error("Stop rescan because there are too many faild cases, #{test_cases.count} > #{failed_test_limit} (threshold).")
    exit 0
  end

  rescan_output_root = params[:output_directory]

  last_exception = nil

  test_cases.each_with_index do |test_case, i|
    retry_output_directory = File.join(rescan_output_root, "rescan", (i + 1).to_s)
    UI.important("Rescan '#{test_case}'.")
    UI.important("Reports are saved '#{retry_output_directory}'.")

    begin
      scan_options = params[:scan]
      scan_options[:only_testing] = [test_case]
      scan_options[:output_directory] = retry_output_directory
      scan_options[:buildlog_path] = retry_output_directory

      scan_params = FastlaneCore::Configuration.create(ScanAction.available_options, scan_options)
      ::Fastlane::Actions::ScanAction.run(scan_params)
    rescue => e
      last_exception = e
    end
  end

  raise last_exception unless last_exception.nil?
end