fastlane-plugin-test_center 3.14.3 → 3.14.4

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
  SHA256:
3
- metadata.gz: e081e2a0d9d6bcb59c38f24072eb0059edef4457f03fed6e2318930260e9f5a4
4
- data.tar.gz: 681403d6200f5d943e28f9c3fa6b90a6f450d7a9252c476eb7cf77c7e0c6101d
3
+ metadata.gz: 4364b9e3e49e3aa1a3bbd1e26feb07e449de72900bcd1ec3341ff8d1b0ca62ad
4
+ data.tar.gz: f983745b33c34838839d546aff4c4e407673c8241e72ab14b695d288792bdac4
5
5
  SHA512:
6
- metadata.gz: 98e979a4fbafe31e6dc33bd1a3a94a1e1da316ce8226c3688e9d223461a33c5d75c9291dc837e256c227915959547f8964df38c524e40b45742408235ee94713
7
- data.tar.gz: 3049728d26e108dea44480f7445e41be419f4189e3bb2b63b8cef7871a9d7bf58b5edcee01351dc40496209f6805706bfcb0b6cf08b9fee6c43bba1decbfecda
6
+ metadata.gz: 1bb52a9bcc82781df58b2ab2b6dd33c1831da0b345b9b51842959b8a372e5341b773cf639e3cb884bccc426336dad01c8ff1e7fc418fad0baefe201e12c46bab
7
+ data.tar.gz: 8d6e6a9321e13aada993f1099f45b7317f4d4c30e8bbdfa55a35a49a1a0dd3aa6c7e06c7dd244132e37d4c149ac0a6b9f94d9198d3f0bd8ee912853fa44f773d
data/README.md CHANGED
@@ -99,7 +99,7 @@ _fastlane_ is the easiest way to automate beta deployments and releases for your
99
99
  ## Supporters
100
100
 
101
101
  ![Владислав Давыдов](https://avatars1.githubusercontent.com/u/47553334?s=44&u=4691860dba898943b947180b3d28bb85851b0d7c&v=4)
102
- [vdavydovHH](https://github.com/vdavydovHH)
102
+ [vdavydovHH](https://github.com/vdavydovHH) ![amelendezSGY](https://avatars1.githubusercontent.com/u/28657466?s=44&v=4)[amelendezSGY](https://github.com/amelendezSGY)
103
103
 
104
104
  ## License
105
105
 
@@ -361,6 +361,14 @@ module Fastlane
361
361
  UI.user_error!("Error: Batch counts must be greater than zero") unless count > 0
362
362
  end
363
363
  ),
364
+ FastlaneCore::ConfigItem.new(
365
+ key: :batches,
366
+ env_name: "FL_MULTI_SCAN_BATCHES",
367
+ description: "The explicit batches (an Array of Arrays of test identifiers) to run either serially, or each batch on a simulator in parallel if :parallel_testrun_count is given",
368
+ type: Array,
369
+ optional: true,
370
+ conflicting_options: [:batch_count]
371
+ ),
364
372
  FastlaneCore::ConfigItem.new(
365
373
  key: :retry_test_runner_failures,
366
374
  description: "Set to true If you want to treat build failures during testing, like 'Test runner exited before starting test execution', as 'all tests failed'",
@@ -375,7 +383,7 @@ module Fastlane
375
383
  is_string: false,
376
384
  default_value: false,
377
385
  optional: true,
378
- conflicting_options: [:batch_count],
386
+ conflicting_options: %i[batch_count batches],
379
387
  conflict_block: proc do |value|
380
388
  UI.user_error!(
381
389
  "Error: Can't use 'invocation_based_tests' and 'batch_count' options in one run, "\
@@ -433,7 +441,7 @@ module Fastlane
433
441
  ),
434
442
  FastlaneCore::ConfigItem.new(
435
443
  key: :testrun_completed_block,
436
- description: 'A block invoked each time a test run completes. When combined with :parallel_testrun_count, will be called separately in each child process',
444
+ description: 'A block invoked each time a test run completes. When combined with :parallel_testrun_count, will be called separately in each child process. Return a Hash with :continue set to false to stop retrying tests, or :only_testing to change which tests will be run in the next try',
437
445
  optional: true,
438
446
  is_string: false,
439
447
  default_value: nil,
@@ -461,6 +469,10 @@ module Fastlane
461
469
 
462
470
  # UI.abort_with_message!('You could conditionally abort')
463
471
  UI.message(\"\\\u1F60A everything is fine, let's continue try \#{try_attempt + 1} for batch \#{batch}\")
472
+ {
473
+ continue: true,
474
+ only_testing: ['AtomicBoyUITests/AtomicBoyUITests/testExample17']
475
+ }
464
476
  end
465
477
 
466
478
  multi_scan(
@@ -486,6 +498,120 @@ module Fastlane
486
498
  output_files: 'report.json',
487
499
  fail_build: false
488
500
  )
501
+ ",
502
+ "
503
+ UI.header('batches feature')
504
+ multi_scan(
505
+ workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
506
+ scheme: 'AtomicBoy',
507
+ try_count: 3,
508
+ fail_build: false,
509
+ batches: [
510
+ [
511
+ 'AtomicBoyUITests/AtomicBoyUITests/testExample5',
512
+ 'AtomicBoyUITests/AtomicBoyUITests/testExample10',
513
+ 'AtomicBoyUITests/AtomicBoyUITests/testExample15'
514
+ ],
515
+ [
516
+ 'AtomicBoyUITests/AtomicBoyUITests/testExample6',
517
+ 'AtomicBoyUITests/AtomicBoyUITests/testExample12',
518
+ 'AtomicBoyUITests/AtomicBoyUITests/testExample18'
519
+ ]
520
+ ]
521
+ )
522
+ "
523
+ ]
524
+ end
525
+
526
+ def self.integration_tests
527
+ [
528
+ "
529
+ UI.header('Basic test')
530
+ multi_scan(
531
+ workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
532
+ scheme: 'AtomicBoy',
533
+ fail_build: false,
534
+ try_count: 2,
535
+ disable_xcpretty: true
536
+ )
537
+ ",
538
+ "
539
+ UI.header('Basic test with 1 specific test')
540
+ multi_scan(
541
+ workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
542
+ scheme: 'AtomicBoy',
543
+ fail_build: false,
544
+ try_count: 2,
545
+ only_testing: ['AtomicBoyUITests/AtomicBoyUITests/testExample']
546
+ )
547
+ ",
548
+ "
549
+ UI.header('Basic test with test target expansion')
550
+ multi_scan(
551
+ workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
552
+ scheme: 'AtomicBoy',
553
+ fail_build: false,
554
+ try_count: 2,
555
+ only_testing: ['AtomicBoyUITests', 'AtomicBoyTests']
556
+ )
557
+ ",
558
+ "
559
+ UI.header('Parallel test run')
560
+ multi_scan(
561
+ workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
562
+ scheme: 'AtomicBoy',
563
+ fail_build: false,
564
+ try_count: 2,
565
+ parallel_testrun_count: 2
566
+ )
567
+ ",
568
+ "
569
+ UI.header('Parallel test run with fewer tests than parallel test runs')
570
+ multi_scan(
571
+ workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
572
+ scheme: 'AtomicBoy',
573
+ fail_build: false,
574
+ try_count: 2,
575
+ parallel_testrun_count: 4,
576
+ only_testing: ['AtomicBoyUITests/AtomicBoyUITests/testExample']
577
+ )
578
+ ",
579
+ "
580
+ UI.header('Basic test with batch count')
581
+ multi_scan(
582
+ workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
583
+ scheme: 'AtomicBoy',
584
+ fail_build: false,
585
+ try_count: 2,
586
+ batch_count: 2
587
+ )
588
+ ",
589
+ "
590
+ UI.header('Basic test with batches')
591
+ multi_scan(
592
+ workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
593
+ scheme: 'AtomicBoy',
594
+ fail_build: false,
595
+ try_count: 2,
596
+ batches: [
597
+ ['AtomicBoyUITests/AtomicBoyUITests/testExample', 'AtomicBoyUITests/AtomicBoyUITests/testExample2'],
598
+ ['AtomicBoyUITests/AtomicBoyUITests/testExample3', 'AtomicBoyUITests/AtomicBoyUITests/testExample4']
599
+ ],
600
+ parallel_testrun_count: 2
601
+ )
602
+ ",
603
+ "
604
+ UI.header('Basic test with xcresult')
605
+ multi_scan(
606
+ workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
607
+ scheme: 'AtomicBoy',
608
+ output_types: 'xcresult',
609
+ output_files: 'result.xcresult',
610
+ collate_reports: false,
611
+ fail_build: false,
612
+ try_count: 2,
613
+ batch_count: 2
614
+ )
489
615
  "
490
616
  ]
491
617
  end
@@ -16,6 +16,7 @@ module TestCenter
16
16
  @options[:output_files],
17
17
  @options[:custom_report_file_name]
18
18
  )
19
+ @callback_overrides_only_testing = false
19
20
  end
20
21
 
21
22
  def before_testrun
@@ -189,7 +190,26 @@ module TestCenter
189
190
  update_json_failure_details(info)
190
191
  update_test_result_bundle_details(info)
191
192
 
192
- @options[:testrun_completed_block].call(info)
193
+ @callback_overrides_only_testing = false
194
+ callback_result = @options[:testrun_completed_block].call(info)
195
+ if callback_result.kind_of?(Hash)
196
+ should_continue = callback_result.fetch(:continue, true)
197
+ if !should_continue
198
+ discontinue_message = 'Following testrun_completed_block\'s request to discontinue testing'
199
+ discontinue_message << " for batch ##{@options[:batch]}" unless @options[:batch].nil?
200
+ FastlaneCore::UI.verbose(discontinue_message)
201
+ @testrun_count = options[:try_count]
202
+ end
203
+ overridden_only_testing = callback_result.fetch(:only_testing, nil)
204
+ if overridden_only_testing && should_continue
205
+ override_only_testing_message = 'Following testrun_completed_block\'s request to change :only_testing to '
206
+ override_only_testing_message << overridden_only_testing.to_s
207
+ override_only_testing_message << " for batch ##{@options[:batch]}" unless @options[:batch].nil?
208
+ FastlaneCore::UI.verbose(override_only_testing_message)
209
+ @callback_overrides_only_testing = true
210
+ @options[:only_testing] = overridden_only_testing
211
+ end
212
+ end
193
213
  end
194
214
 
195
215
  def failure_details(additional_info)
@@ -242,6 +262,8 @@ module TestCenter
242
262
  end
243
263
 
244
264
  def update_only_testing
265
+ return if @callback_overrides_only_testing
266
+
245
267
  report_filepath = File.join(output_directory, @reportnamer.junit_last_reportname)
246
268
  config = FastlaneCore::Configuration.create(
247
269
  Fastlane::Actions::TestsFromJunitAction.available_options,
@@ -65,8 +65,8 @@ module TestCenter
65
65
 
66
66
  @test_collector = TestCollector.new(@options)
67
67
  @options.reject! { |key| %i[testplan].include?(key) }
68
- @batch_count = @test_collector.test_batches.size
69
- tests = @test_collector.test_batches.flatten
68
+ @batch_count = @test_collector.batches.size
69
+ tests = @test_collector.batches.flatten
70
70
  if tests.size < @options[:parallel_testrun_count].to_i
71
71
  FastlaneCore::UI.important(":parallel_testrun_count greater than the number of tests (#{tests.size}). Reducing to that number.")
72
72
  @options[:parallel_testrun_count] = tests.size
@@ -196,7 +196,7 @@ module TestCenter
196
196
  pool = TestBatchWorkerPool.new(pool_options)
197
197
  pool.setup_workers
198
198
 
199
- remaining_test_batches = @test_collector.test_batches.clone
199
+ remaining_test_batches = @test_collector.batches.clone
200
200
  remaining_test_batches.each_with_index do |test_batch, current_batch_index|
201
201
  worker = pool.wait_for_worker
202
202
  FastlaneCore::UI.message("Starting test run #{current_batch_index + 1}")
@@ -209,7 +209,7 @@ module TestCenter
209
209
  end
210
210
 
211
211
  def scan_options_for_worker(test_batch, batch_index)
212
- if @test_collector.test_batches.size > 1
212
+ if @test_collector.batches.size > 1
213
213
  # If there are more than 1 batch, then we want each batch result
214
214
  # sent to a "batch index" output folder to be collated later
215
215
  # into the requested output_folder.
@@ -3,34 +3,154 @@ module TestCenter
3
3
  require 'fastlane_core/ui/ui.rb'
4
4
  require 'fastlane/actions/scan'
5
5
  require 'plist'
6
+ require 'set'
6
7
 
7
8
  class TestCollector
8
9
  attr_reader :xctestrun_path
9
- attr_reader :only_testing
10
+ attr_reader :batches
11
+ attr_reader :testables
10
12
 
11
13
  def initialize(options)
12
- unless options[:xctestrun] || options[:derived_data_path]
13
- options[:derived_data_path] = default_derived_data_path(options)
14
+ @invocation_based_tests = options[:invocation_based_tests]
15
+ @swift_test_prefix = options[:swift_test_prefix]
16
+
17
+ @xctestrun_path = self.class.xctestrun_filepath(options)
18
+ initialize_batches(options)
19
+ end
20
+
21
+ private
22
+
23
+ def initialize_batches(options)
24
+ if options[:batches]
25
+ expand_given_batches_to_full_test_identifiers(options)
26
+ else
27
+ derive_batches_from_tests(options)
14
28
  end
15
- @xctestrun_path = options[:xctestrun] || derived_testrun_path(options[:derived_data_path], options[:scheme])
16
- unless @xctestrun_path && File.exist?(@xctestrun_path)
17
- FastlaneCore::UI.user_error!("Error: cannot find xctestrun file '#{@xctestrun_path}'")
29
+ end
30
+
31
+ def expand_given_batches_to_full_test_identifiers(options)
32
+ @batches = options[:batches]
33
+ testables = Set.new
34
+ @batches.each do |batch|
35
+ expand_test_identifiers(batch)
36
+ batch.each { |t| testables << t.split('/')[0] }
18
37
  end
19
- @only_testing = options[:only_testing] || only_testing_from_testplan(options)
20
- if @only_testing.kind_of?(String)
21
- @only_testing = @only_testing.split(',')
38
+ @testables = testables.to_a
39
+ end
40
+
41
+ def derive_batch_count(options)
42
+ batch_count = options.fetch(:batch_count, 1)
43
+ if batch_count == 1 && options.fetch(:parallel_testrun_count, 0) > 1
44
+ # if the batch count is 1, and the users wants parallel runs
45
+ # we *must* set the batch count to the same number of parallel
46
+ # runs or else the desired reports will not be written
47
+ batch_count = options[:parallel_testrun_count]
22
48
  end
23
- @skip_testing = options[:skip_testing]
24
- @invocation_based_tests = options[:invocation_based_tests]
25
- @batch_count = options[:batch_count]
26
- if @batch_count == 1 && options[:parallel_testrun_count] > 1
27
- @batch_count = options[:parallel_testrun_count]
49
+ batch_count
50
+ end
51
+
52
+ def derive_only_testing(options)
53
+ only_testing = options[:only_testing] || self.class.only_testing_from_testplan(options)
54
+ if only_testing && only_testing.kind_of?(String)
55
+ only_testing = only_testing.split(',').map(&:strip)
28
56
  end
57
+ only_testing
58
+ end
29
59
 
30
- @swift_test_prefix = options[:swift_test_prefix]
60
+ def testable_tests_hash_from_options(options)
61
+ testable_tests_hash = Hash.new { |h, k| h[k] = [] }
62
+ only_testing = derive_only_testing(options)
63
+ if only_testing
64
+ expand_test_identifiers(only_testing)
65
+ only_testing.each do |test_identifier|
66
+ testable = test_identifier.split('/')[0]
67
+ testable_tests_hash[testable] << test_identifier
68
+ end
69
+ else
70
+ testable_tests_hash = xctestrun_known_tests.clone
71
+ if options[:skip_testing]
72
+ expand_test_identifiers(options[:skip_testing])
73
+ testable_tests_hash.each do |testable, test_identifiers|
74
+ test_identifiers.replace(test_identifiers - options[:skip_testing])
75
+ testable_tests_hash.delete(testable) if test_identifiers.empty?
76
+ end
77
+ end
78
+ end
79
+ testable_tests_hash
80
+ end
81
+
82
+ def derive_batches_from_tests(options)
83
+ @batches = []
84
+ testable_tests_hash = testable_tests_hash_from_options(options)
85
+ @testables = testable_tests_hash.keys
86
+ batch_count = derive_batch_count(options)
87
+ testable_tests_hash.each do |testable, test_identifiers|
88
+ next if test_identifiers.empty?
89
+
90
+ if batch_count > 1
91
+ slice_count = [(test_identifiers.length / batch_count.to_f).ceil, 1].max
92
+ test_identifiers.each_slice(slice_count).to_a.each do |batch|
93
+ @batches << batch
94
+ end
95
+ else
96
+ @batches << test_identifiers
97
+ end
98
+ end
99
+ end
100
+
101
+ def expand_test_identifiers(test_identifiers)
102
+ all_known_tests = nil
103
+ test_identifiers.each_with_index do |test_identifier, index|
104
+ test_components = test_identifier.split('/')
105
+ is_full_test_identifier = (test_components.size == 3)
106
+ next if is_full_test_identifier
107
+
108
+ all_known_tests ||= xctestrun_known_tests.clone
109
+
110
+ testsuite = ''
111
+ testable = test_components[0]
112
+ expanded_test_identifiers = []
113
+ if test_components.size == 1
114
+ # this is a testable, also known as a test target. Let's expand it out
115
+ # to all of its tests. Note: a test target can have many testSuites, each
116
+ # with their own testCases.
117
+ if all_known_tests[testable].to_a.empty?
118
+ FastlaneCore::UI.verbose("Unable to expand #{testable} to constituent tests")
119
+ expand_test_identifiers = [testable]
120
+ else
121
+ expand_test_identifiers = all_known_tests[testable]
122
+ end
123
+ else
124
+ # this is a testable and a test suite, let's expand it out to all of
125
+ # its testCases. Note: if the user put the same test identifier in more than
126
+ # one place in this array, this could lead to multiple repititions of the same
127
+ # set of test identifiers
128
+ testsuite = test_components[1]
129
+ expanded_test_identifiers = all_known_tests[testable].select do |known_test|
130
+ known_test.split('/')[1] == testsuite
131
+ end
132
+ end
133
+ test_identifiers.delete_at(index)
134
+ test_identifiers.insert(index, *expand_test_identifiers)
135
+ end
136
+ end
137
+
138
+ def xctestrun_known_tests
139
+ unless @known_tests
140
+ config = FastlaneCore::Configuration.create(
141
+ ::Fastlane::Actions::TestsFromXctestrunAction.available_options,
142
+ {
143
+ xctestrun: @xctestrun_path,
144
+ invocation_based_tests: @invocation_based_tests,
145
+ swift_test_prefix: @swift_test_prefix
146
+ }
147
+ )
148
+ @known_tests = ::Fastlane::Actions::TestsFromXctestrunAction.run(config)
149
+ end
150
+ @known_tests
31
151
  end
32
152
 
33
- def only_testing_from_testplan(options)
153
+ def self.only_testing_from_testplan(options)
34
154
  return unless options[:testplan] && options[:scheme]
35
155
 
36
156
  config = FastlaneCore::Configuration.create(
@@ -60,153 +180,26 @@ module TestCenter
60
180
  return test_options[:only_testing]
61
181
  end
62
182
 
63
- def default_derived_data_path(options)
183
+ def self.default_derived_data_path
64
184
  project_derived_data_path = Scan.project.build_settings(key: "BUILT_PRODUCTS_DIR")
65
185
  File.expand_path("../../..", project_derived_data_path)
66
186
  end
67
187
 
68
- def derived_testrun_path(derived_data_path, scheme)
188
+ def self.derived_testrun_path(derived_data_path)
69
189
  xctestrun_files = Dir.glob("#{derived_data_path}/Build/Products/*.xctestrun")
70
190
  xctestrun_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) }.last
71
191
  end
72
192
 
73
- def testables
74
- unless @testables
75
- if @only_testing
76
- @testables ||= only_testing_to_testables_tests.keys
77
- else
78
- @testables = xctestrun_known_tests.keys
79
- end
80
- end
81
- @testables
82
- end
83
-
84
- def only_testing_to_testables_tests
85
- tests = Hash.new { |h, k| h[k] = [] }
86
- @only_testing.sort.each do |test_identifier|
87
- testable = test_identifier.split('/', 2)[0]
88
- tests[testable] << test_identifier
89
- end
90
- tests
91
- end
92
-
93
- def xctestrun_known_tests
94
- unless @known_tests
95
- config = FastlaneCore::Configuration.create(
96
- ::Fastlane::Actions::TestsFromXctestrunAction.available_options,
97
- {
98
- xctestrun: @xctestrun_path,
99
- invocation_based_tests: @invocation_based_tests,
100
- swift_test_prefix: @swift_test_prefix
101
- }
102
- )
103
- @known_tests = ::Fastlane::Actions::TestsFromXctestrunAction.run(config)
104
- end
105
- @known_tests
106
- end
107
-
108
- def expand_short_testidentifiers_to_tests(testables_tests)
109
- # Remember, testable_tests is of the format:
110
- # {
111
- # 'testable1' => [
112
- # 'testsuite1/testcase1',
113
- # 'testsuite1/testcase2',
114
- # 'testsuite2/testcase1',
115
- # 'testsuite2/testcase2',
116
- # ...
117
- # 'testsuiteN/testcase1', ... 'testsuiteN/testcaseM'
118
- # ],
119
- # ...
120
- # 'testableO' => [
121
- # 'testsuite1/testcase1',
122
- # 'testsuite1/testcase2',
123
- # 'testsuite2/testcase1',
124
- # 'testsuite2/testcase2',
125
- # ...
126
- # 'testsuiteN/testcase1', ... 'testsuiteN/testcaseM'
127
- # ]
128
- # }
129
- return if @invocation_based_tests
130
-
131
- # iterate among all the test identifers for each testable
132
- # A test identifier is seperated into components by '/'
133
- # if a test identifier has only 2 separators, it probably is
134
- # 'testable/testsuite' (but it could be 'testsuite/testcase' )
135
- all_known_tests = nil
136
- known_tests = []
137
- testables_tests.each do |testable, tests|
138
- tests.each_with_index do |test, index|
139
- test_components = test.split('/')
140
- is_full_test_identifier = (test_components.size == 3)
141
- next if is_full_test_identifier
142
-
143
- all_known_tests ||= xctestrun_known_tests.clone
144
-
145
- testsuite = ''
146
- if test_components.size == 1
147
- if test_components[0] == testable
148
- # The following || [] is just in case the user provided multiple
149
- # test targets or there are no actual tests found.
150
- testables_tests[testable][index] = all_known_tests[testable] || []
151
- all_known_tests.delete(testable)
152
- next
153
- end
154
-
155
- testsuite = test_components[0]
156
- else
157
- testsuite = test_components[1]
158
- end
159
-
160
- testables_tests[testable][index], all_known_tests[testable] = all_known_tests[testable].partition do |known_test|
161
- known_test.split('/')[1] == testsuite
162
- end
163
- end
164
- testables_tests[testable].flatten!
165
- end
166
- end
167
-
168
- def testables_tests
169
- unless @testables_tests
170
- if @only_testing
171
- @testables_tests = only_testing_to_testables_tests
172
- expand_short_testidentifiers_to_tests(@testables_tests)
173
- else
174
- @testables_tests = xctestrun_known_tests
175
- if @skip_testing
176
- skipped_testable_tests = Hash.new { |h, k| h[k] = [] }
177
- @skip_testing.sort.each do |skipped_test_identifier|
178
- testable = skipped_test_identifier.split('/', 2)[0]
179
- skipped_testable_tests[testable] << skipped_test_identifier
180
- end
181
- @testables_tests.each_key do |testable|
182
- @testables_tests[testable] -= skipped_testable_tests[testable]
183
- end
184
- end
185
- end
193
+ def self.xctestrun_filepath(options)
194
+ unless options[:xctestrun] || options[:derived_data_path]
195
+ options[:derived_data_path] = default_derived_data_path
186
196
  end
197
+ path = (options[:xctestrun] || derived_testrun_path(options[:derived_data_path]))
187
198
 
188
- @testables_tests
189
- end
190
-
191
- def test_batches
192
- if @batches.nil?
193
- @batches = []
194
- testables.each do |testable|
195
- testable_tests = testables_tests[testable]
196
- next if testable_tests.empty?
197
-
198
- if @batch_count > 1
199
- slice_count = [(testable_tests.length / @batch_count.to_f).ceil, 1].max
200
- testable_tests.each_slice(slice_count).to_a.each do |tests_batch|
201
- @batches << tests_batch
202
- end
203
- else
204
- @batches << testable_tests
205
- end
206
- end
199
+ unless path && File.exist?(path)
200
+ FastlaneCore::UI.user_error!("Error: cannot find xctestrun file '#{path}'")
207
201
  end
208
-
209
- @batches
202
+ path
210
203
  end
211
204
  end
212
205
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TestCenter
3
- VERSION = "3.14.3"
3
+ VERSION = "3.14.4"
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: 3.14.3
4
+ version: 3.14.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lyndsey Ferguson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-15 00:00:00.000000000 Z
11
+ date: 2020-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json