fastlane-plugin-test_center 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c0492510b50e99b3ef9af5f894d1032b91b3580a
4
- data.tar.gz: d61ce22bb9c6bcb7247aaf9d42443ee8603adcdc
3
+ metadata.gz: 270262acce80a1f4e13f63b7e3926d3a2664932b
4
+ data.tar.gz: 42ccbeb22f3661ef6c770f4f020a2e72c44b68da
5
5
  SHA512:
6
- metadata.gz: 6bb763825223bfa13d2b49b06360dc492d001d6a9f78c161203d6abe5e7d0e55aac55cfb6a31d889fc42859ac4a4b616697ccf532afea2bf64e0d73bfcf8b1ae
7
- data.tar.gz: ae99b357e3c09786de940057a105b623302e59faca20ecbeb7c7f61646b116ec5944f886b773105cfb27187c62acee026e1f44b5d2ce8b2dd2c2140d98a7e75f
6
+ metadata.gz: aaefef06f68566da00b2bd6e4c6ffaeb0e734e0cf9b1f2eb2b504c08c7e7dba6f1189d8d0061f45ea54821fb65094949c3433a2836b596ec5066985aa0b387eb
7
+ data.tar.gz: e258386f7567d2e2c4297628c73e97f0387446632bea9c05bd31c6da0feab3fcd74e3bf6cf48cce5e3629312f1df2ec0dc638062ead05d0312b73f59012384be
@@ -24,6 +24,8 @@ module Fastlane
24
24
  if target_testcase
25
25
  target_testcase.parent.insert_after(target_testcase, testcase)
26
26
  target_testcase.parent.delete_element(target_testcase)
27
+ else
28
+ target_testsuite << testcase
27
29
  end
28
30
  end
29
31
  else
@@ -2,11 +2,12 @@ module Fastlane
2
2
  module Actions
3
3
  require 'fastlane/actions/scan'
4
4
  require 'shellwords'
5
+ require 'xctest_list'
6
+ require 'plist'
5
7
 
6
8
  class MultiScanAction < Action
7
9
  def self.run(params)
8
- try_count = 0
9
- scan_options = params.values.reject { |k| k == :try_count }
10
+ scan_options = params.values.reject { |k| %i[try_count batch_count].include?(k) }
10
11
 
11
12
  unless Helper.test?
12
13
  FastlaneCore::PrintTable.print_values(
@@ -23,21 +24,38 @@ module Fastlane
23
24
  scan_options[:test_without_building] = true
24
25
  end
25
26
 
27
+ batch_count = params[:batch_count]
28
+ if batch_count == 1
29
+ try_scan_with_retry(scan_options, params[:try_count])
30
+ else
31
+ tests = tests_to_batch(scan_options)
32
+ tests.each_slice((tests.length / batch_count.to_f).round).to_a.each do |tests_batch|
33
+ scan_options.reject! { |key| key == :skip_testing }
34
+ scan_options[:only_testing] = tests_batch
35
+ try_scan_with_retry(scan_options, params[:try_count])
36
+ end
37
+ end
38
+ collate_reports(scan_options)
39
+ end
40
+
41
+ def self.try_scan_with_retry(scan_options, maximum_try_count)
42
+ try_count = 0
26
43
  begin
27
44
  try_count += 1
28
45
  config = FastlaneCore::Configuration.create(Fastlane::Actions::ScanAction.available_options, scan_options)
29
46
  Fastlane::Actions::ScanAction.run(config)
30
47
  rescue FastlaneCore::Interface::FastlaneTestFailure => e
31
48
  UI.verbose("Scan failed with #{e}")
32
- if try_count < params[:try_count]
49
+ if try_count < maximum_try_count
33
50
  report_filepath = junit_report_filepath(scan_options)
34
51
  failed_tests = other_action.tests_from_junit(junit: report_filepath)[:failed]
35
52
  scan_options[:only_testing] = failed_tests.map(&:shellescape)
36
53
  increment_report_filenames(scan_options)
37
54
  retry
38
55
  end
56
+ else
57
+ increment_report_filenames(scan_options)
39
58
  end
40
- collate_reports(scan_options)
41
59
  end
42
60
 
43
61
  def self.collate_reports(scan_options)
@@ -53,18 +71,98 @@ module Fastlane
53
71
  final_report_name = "#{match[:filename]}#{extension}"
54
72
  end
55
73
  other_action.collate_junit_reports(
56
- reports: report_files.reverse,
74
+ reports: report_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
57
75
  collated_report: File.absolute_path(File.join(scan_options[:output_directory], final_report_name))
58
76
  )
59
77
  end
60
78
  FileUtils.rm_f(Dir.glob("#{scan_options[:output_directory]}/*-[1-9]*#{extension}"))
61
79
  end
62
80
 
81
+ def self.kill(program)
82
+ Actions.sh("killall -9 '#{program}' &> /dev/null || true", log: false)
83
+ end
84
+
85
+ def self.quit_simulators
86
+ kill('iPhone Simulator')
87
+ kill('Simulator')
88
+ kill('SimulatorBridge')
89
+
90
+ launchctl_list_count = 0
91
+ while Actions.sh('launchctl list | grep com.apple.CoreSimulator.CoreSimulatorService || true', log: false) != ''
92
+ break if (launchctl_list_count += 1) > 10
93
+ Actions.sh('launchctl remove com.apple.CoreSimulator.CoreSimulatorService &> /dev/null || true', log: false)
94
+ sleep(1)
95
+ end
96
+ end
97
+
98
+ def self.tests_to_batch(scan_options)
99
+ unless scan_options[:only_testing].nil?
100
+ return scan_options[:only_testing]
101
+ end
102
+
103
+ xctestrun_path = scan_options[:xctestrun] || testrun_path(scan_options)
104
+ if xctestrun_path.nil? || !File.exist?(xctestrun_path)
105
+ UI.user_error!("Error: cannot find expected xctestrun file '#{xctestrun_path}'")
106
+ end
107
+ tests = xctestrun_tests(xctestrun_path)
108
+ remove_skipped_tests(tests, scan_options[:skip_testing])
109
+ end
110
+
111
+ def self.remove_skipped_tests(tests_to_batch, tests_to_skip)
112
+ if tests_to_skip.nil?
113
+ return tests_to_batch
114
+ end
115
+
116
+ if tests_to_skip
117
+ tests_to_skip = tests_to_skip
118
+ testsuites_to_skip = tests_to_skip.select do |testsuite|
119
+ testsuite.count('/') == 1 # just the testable/testsuite
120
+ end
121
+ tests_to_skip -= testsuites_to_skip
122
+ tests_to_batch.reject! do |test_identifier|
123
+ test_suite = test_identifier.split('/').first(2).join('/')
124
+ testsuites_to_skip.include?(test_suite)
125
+ end
126
+ tests_to_batch -= tests_to_skip
127
+ end
128
+ tests_to_batch
129
+ end
130
+
131
+ def self.xctestrun_tests(xctestrun_path)
132
+ xctestrun = Plist.parse_xml(xctestrun_path)
133
+ xctestrun_rootpath = File.dirname(xctestrun_path)
134
+ tests = []
135
+ xctestrun.each do |testable_name, xctestrun_config|
136
+ test_identifiers = XCTestList.tests(xctest_bundle_path(xctestrun_rootpath, xctestrun_config))
137
+ if xctestrun_config.key?('SkipTestIdentifiers')
138
+ test_identifiers.reject! { |test_identifier| xctestrun_config['SkipTestIdentifiers'].include?(test_identifier) }
139
+ end
140
+ tests += test_identifiers.map do |test_identifier|
141
+ "#{testable_name.shellescape}/#{test_identifier}"
142
+ end
143
+ end
144
+ tests
145
+ end
146
+
147
+ def self.xctest_bundle_path(xctestrun_rootpath, xctestrun_config)
148
+ xctest_host_path = xctestrun_config['TestHostPath'].sub('__TESTROOT__', xctestrun_rootpath)
149
+ xctestrun_config['TestBundlePath'].sub('__TESTHOST__', xctest_host_path)
150
+ end
151
+
152
+ def self.testrun_path(scan_options)
153
+ Dir.glob("#{scan_options[:derived_data_path]}/Build/Products/#{scan_options[:scheme]}*.xctestrun").first
154
+ end
155
+
156
+ def self.test_products_path(derived_data_path)
157
+ File.join(derived_data_path, "Build", "Products")
158
+ end
159
+
63
160
  def self.build_for_testing(scan_options)
64
161
  scan_options.delete(:test_without_building)
65
162
  scan_options[:build_for_testing] = true
66
163
  config = FastlaneCore::Configuration.create(Fastlane::Actions::ScanAction.available_options, scan_options)
67
164
  Fastlane::Actions::ScanAction.run(config)
165
+ scan_options[:derived_data_path] = Scan.config[:derived_data_path]
68
166
  end
69
167
 
70
168
  def self.config_has_junit_report(config)
@@ -158,6 +256,18 @@ module Fastlane
158
256
  type: Integer,
159
257
  is_string: false,
160
258
  default_value: 1
259
+ ),
260
+ FastlaneCore::ConfigItem.new(
261
+ key: :batch_count,
262
+ env_name: "FL_MULTI_SCAN_BATCH_COUNT",
263
+ description: "The number of test batches to run through scan. Can be combined with :try_count",
264
+ type: Integer,
265
+ is_string: false,
266
+ default_value: 1,
267
+ optional: true,
268
+ verify_block: proc do |count|
269
+ UI.user_error!("Error: Batch counts must be greater than zero") unless count > 0
270
+ end
161
271
  )
162
272
  ]
163
273
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TestCenter
3
- VERSION = "2.3.1"
3
+ VERSION = "2.4.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-test_center
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lyndsey Ferguson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-25 00:00:00.000000000 Z
11
+ date: 2018-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xcodeproj
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: xctest_list
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: plist
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement