fastlane-plugin-test_center 3.2.2 → 3.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +362 -4
- data/lib/fastlane/plugin/test_center/actions/collate_html_reports.rb +15 -0
- data/lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb +15 -0
- data/lib/fastlane/plugin/test_center/actions/multi_scan.rb +129 -29
- data/lib/fastlane/plugin/test_center/actions/suppress_tests.rb +32 -0
- data/lib/fastlane/plugin/test_center/actions/suppress_tests_from_junit.rb +34 -0
- data/lib/fastlane/plugin/test_center/actions/suppressed_tests.rb +25 -0
- data/lib/fastlane/plugin/test_center/actions/tests_from_junit.rb +14 -0
- data/lib/fastlane/plugin/test_center/actions/tests_from_xctestrun.rb +28 -0
- data/lib/fastlane/plugin/test_center/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 961236fb8c29c5f451a7e5e2be5a324baabbc8da
|
4
|
+
data.tar.gz: 293007ce8ea7aea95e82a713b53b396fe7892b53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d3a6001e102082ffeb8898e4fc3bcb5c365dbbe2e01a9e6daadceb1358d7841d789b77f302d19d070ad4b18f5e8becbfdabf0ea4f74989e638ad9e93bb2e79e
|
7
|
+
data.tar.gz: c84228b54f8a6e6f2163a60f4a851cce3935fa1d00c65e26baeb20fcb650bae905edcbe093b74234332cff60bcde1e7be843cdae76190613fe3a565abb471a08
|
data/README.md
CHANGED
@@ -61,7 +61,7 @@ The `test_center` plugin started with a problem when working on automated iOS te
|
|
61
61
|
`multi_scan` began when I engineered an action to only re-run the failed tests in order to determine which ones were truly failing, or just failing randomly due to a fragile infrastructure. This action morphed into an entire plugin with many actions related to tests.
|
62
62
|
|
63
63
|
This fastlane plugin includes the following actions:
|
64
|
-
- [`multi_scan`](#
|
64
|
+
- [`multi_scan`](#multi_scan): gives you control over how your tests are exercised.
|
65
65
|
- [`suppress_tests_from_junit`](#suppress_tests_from_junit): from a test report, suppresses tests in your project.
|
66
66
|
- [`suppress_tests`](#suppress_tests): from a provided list, suppresses tests in your project.
|
67
67
|
- [`suppressed_tests`](#suppressed_tests): returns a list of the suppressed tests in your project.
|
@@ -70,7 +70,7 @@ This fastlane plugin includes the following actions:
|
|
70
70
|
- [`collate_junit_reports`](#collate_junit_reports): combines multiple junit test reports into one report.
|
71
71
|
- [`collate_html_reports`](#collate_html_reports): combines multiple html test reports into one report.
|
72
72
|
|
73
|
-
###
|
73
|
+
### multi_scan 🎉
|
74
74
|
|
75
75
|
Is the fragile test infrastructure provided by `xcodebuild` failing tests inexplicably and getting you down 😢? Use the `:try_count` option to re-run those failed tests multiple times to ensure that any fragility is ironed out and only truly failing tests appear.
|
76
76
|
|
@@ -80,39 +80,397 @@ Do you get frustrated when your automated test system keeps running after the fr
|
|
80
80
|
|
81
81
|
Do you have multiple test targets and the normal operation of `scan` is providing you a test report that implies that all the tests ran in one test target? Don't worry, `multi_scan` has fixed that.
|
82
82
|
|
83
|
+
<details>
|
84
|
+
<summary>Example Code:</summary>
|
85
|
+
<!-- multi_scan examples: begin -->
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
|
89
|
+
UI.important(
|
90
|
+
'example: ' \
|
91
|
+
'run tests for a scheme that has two test targets, re-trying up to 2 times if ' \
|
92
|
+
'tests fail. Turn off the default behavior of failing the build if, at the ' \
|
93
|
+
'end of the action, there were 1 or more failing tests.'
|
94
|
+
)
|
95
|
+
summary = multi_scan(
|
96
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
97
|
+
scheme: 'AtomicBoy',
|
98
|
+
try_count: 3,
|
99
|
+
fail_build: false,
|
100
|
+
output_files: 'report.html',
|
101
|
+
output_types: 'html'
|
102
|
+
)
|
103
|
+
UI.success("multi_scan passed? #{summary[:result]}")
|
104
|
+
|
105
|
+
```
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
|
109
|
+
UI.important(
|
110
|
+
'example: ' \
|
111
|
+
'run tests for a scheme that has two test targets, re-trying up to 2 times if ' \
|
112
|
+
'tests fail. Make sure that the default behavior of failing the build works.'
|
113
|
+
)
|
114
|
+
begin
|
115
|
+
multi_scan(
|
116
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
117
|
+
scheme: 'AtomicBoy',
|
118
|
+
try_count: 2
|
119
|
+
)
|
120
|
+
rescue FastlaneCore::Interface::FastlaneTestFailure => e
|
121
|
+
UI.success("failed successfully with #{e.message}")
|
122
|
+
else
|
123
|
+
raise 'This should have failed'
|
124
|
+
end
|
125
|
+
|
126
|
+
```
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
|
130
|
+
UI.important(
|
131
|
+
'example: ' \
|
132
|
+
'split the tests into 2 batches and run each batch of tests up to 3 ' \
|
133
|
+
'times if tests fail. Do not fail the build.'
|
134
|
+
)
|
135
|
+
multi_scan(
|
136
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
137
|
+
scheme: 'AtomicBoy',
|
138
|
+
try_count: 3,
|
139
|
+
batch_count: 2,
|
140
|
+
fail_build: false
|
141
|
+
)
|
142
|
+
|
143
|
+
```
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
|
147
|
+
UI.important(
|
148
|
+
'example: ' \
|
149
|
+
'split the tests into 2 batches and run each batch of tests up to 3 ' \
|
150
|
+
'times if tests fail. Abort the testing early if there are too many ' \
|
151
|
+
'failing tests by passing in a :testrun_completed_block that is called ' \
|
152
|
+
'by :multi_scan after each run of tests.'
|
153
|
+
)
|
154
|
+
test_run_block = lambda do |testrun_info|
|
155
|
+
failed_test_count = testrun_info[:failed].size
|
156
|
+
passed_test_count = testrun_info[:passing].size
|
157
|
+
try_attempt = testrun_info[:try_count]
|
158
|
+
batch = testrun_info[:batch]
|
159
|
+
|
160
|
+
if passed_test_count > 0 && failed_test_count > passed_test_count / 2
|
161
|
+
UI.abort_with_message!("Too many tests are failing")
|
162
|
+
end
|
163
|
+
UI.message("\ὠA everything is fine, let's continue try #{try_attempt + 1} for batch #{batch}")
|
164
|
+
end
|
165
|
+
|
166
|
+
multi_scan(
|
167
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
168
|
+
scheme: 'AtomicBoy',
|
169
|
+
try_count: 3,
|
170
|
+
batch_count: 2,
|
171
|
+
fail_build: false,
|
172
|
+
testrun_completed_block: test_run_block
|
173
|
+
)
|
174
|
+
|
175
|
+
```
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
|
179
|
+
UI.important(
|
180
|
+
'example: ' \
|
181
|
+
'use the :workspace parameter instead of the :project parameter to find, ' \
|
182
|
+
'build, and test the iOS app.'
|
183
|
+
)
|
184
|
+
multi_scan(
|
185
|
+
workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
|
186
|
+
scheme: 'AtomicBoy',
|
187
|
+
try_count: 3
|
188
|
+
)
|
189
|
+
|
190
|
+
```
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
|
194
|
+
UI.important(
|
195
|
+
'example: ' \
|
196
|
+
'use the :workspace parameter instead of the :project parameter to find, ' \
|
197
|
+
'build, and test the iOS app. Use the :skip_build parameter to not rebuild.'
|
198
|
+
)
|
199
|
+
multi_scan(
|
200
|
+
workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
|
201
|
+
scheme: 'AtomicBoy',
|
202
|
+
skip_build: true,
|
203
|
+
clean: true,
|
204
|
+
try_count: 3,
|
205
|
+
result_bundle: true
|
206
|
+
)
|
207
|
+
|
208
|
+
```
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
|
212
|
+
UI.important(
|
213
|
+
'example: ' \
|
214
|
+
'multi_scan also works with just one test target in the Scheme.'
|
215
|
+
)
|
216
|
+
multi_scan(
|
217
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
218
|
+
scheme: 'Professor',
|
219
|
+
try_count: 3,
|
220
|
+
custom_report_file_name: 'atomic_report.xml',
|
221
|
+
output_types: 'junit,html',
|
222
|
+
fail_build: false
|
223
|
+
)
|
224
|
+
|
225
|
+
```
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
|
229
|
+
UI.important(
|
230
|
+
'example: ' \
|
231
|
+
'multi_scan also can also run just the tests passed in the ' \
|
232
|
+
':only_testing option.'
|
233
|
+
)
|
234
|
+
multi_scan(
|
235
|
+
workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
|
236
|
+
scheme: 'AtomicBoy',
|
237
|
+
try_count: 3,
|
238
|
+
only_testing: ['AtomicBoyTests']
|
239
|
+
)
|
240
|
+
|
241
|
+
```
|
242
|
+
<!-- multi_scan examples: end -->
|
243
|
+
</details>
|
244
|
+
|
83
245
|
### suppress_tests_from_junit
|
84
246
|
|
85
247
|
No time to fix a failing test? Suppress the `:failed` tests in your project and create and prioritize a ticket in your bug tracking system.
|
86
248
|
|
87
249
|
Want to create a special CI job that only re-tries failing tests? Suppress the `:passing` tests in your project and exercise your fragile tests.
|
88
250
|
|
251
|
+
<details>
|
252
|
+
<summary>Example Code:</summary>
|
253
|
+
<!-- suppress_tests_from_junit examples: begin -->
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
|
257
|
+
UI.important(
|
258
|
+
'example: ' \
|
259
|
+
'suppress the tests that failed in the junit report for _all_ Schemes'
|
260
|
+
)
|
261
|
+
suppress_tests_from_junit(
|
262
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
263
|
+
junit: './spec/fixtures/junit.xml',
|
264
|
+
suppress_type: :failed
|
265
|
+
)
|
266
|
+
UI.message(
|
267
|
+
"Suppressed tests for project: #{suppressed_tests(xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj')}"
|
268
|
+
)
|
269
|
+
|
270
|
+
```
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
|
274
|
+
UI.important(
|
275
|
+
'example: ' \
|
276
|
+
'suppress the tests that failed in the junit report for _one_ Scheme'
|
277
|
+
)
|
278
|
+
suppress_tests_from_junit(
|
279
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
280
|
+
junit: './spec/fixtures/junit.xml',
|
281
|
+
scheme: 'Professor',
|
282
|
+
suppress_type: :failed
|
283
|
+
)
|
284
|
+
UI.message(
|
285
|
+
"Suppressed tests for the 'Professor' scheme: #{suppressed_tests(xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj')}"
|
286
|
+
)
|
287
|
+
|
288
|
+
```
|
289
|
+
<!-- suppress_tests_from_junit examples: end -->
|
290
|
+
</details>
|
291
|
+
|
89
292
|
### suppress_tests
|
90
293
|
|
91
294
|
Have some tests that you want turned off? Give the list to this action in order to suppress them for your project.
|
92
295
|
|
296
|
+
<details>
|
297
|
+
<summary>Example Code:</summary>
|
298
|
+
<!-- suppress_tests examples: begin -->
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
|
302
|
+
UI.important(
|
303
|
+
'example: ' \
|
304
|
+
'suppress some tests in all Schemes for a Project'
|
305
|
+
)
|
306
|
+
suppress_tests(
|
307
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
308
|
+
tests: [
|
309
|
+
'AtomicBoyUITests/HappyNapperTests/testBeepingNonExistentFriendDisplaysError',
|
310
|
+
'AtomicBoyUITests/GrumpyWorkerTests'
|
311
|
+
]
|
312
|
+
)
|
313
|
+
|
314
|
+
```
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
|
318
|
+
UI.important(
|
319
|
+
'example: ' \
|
320
|
+
'suppress some tests in one Scheme for a Project'
|
321
|
+
)
|
322
|
+
suppress_tests(
|
323
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
324
|
+
tests: [
|
325
|
+
'AtomicBoyUITests/HappyNapperTests/testBeepingNonExistentFriendDisplaysError',
|
326
|
+
'AtomicBoyUITests/GrumpyWorkerTests'
|
327
|
+
],
|
328
|
+
scheme: 'Professor'
|
329
|
+
)
|
330
|
+
|
331
|
+
```
|
332
|
+
<!-- suppress_tests examples: end -->
|
333
|
+
</details>
|
334
|
+
|
93
335
|
### suppressed_tests
|
94
336
|
|
95
337
|
Do you have an automated process that requires the list of suppressed tests in your project? Use this action to get that.
|
96
338
|
|
339
|
+
<details>
|
340
|
+
<summary>Example Code:</summary>
|
341
|
+
<!-- suppressed_tests examples: begin -->
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
|
345
|
+
UI.important(
|
346
|
+
'example: ' \
|
347
|
+
'get the tests that are suppressed in a Scheme in the Project'
|
348
|
+
)
|
349
|
+
tests = suppressed_tests(
|
350
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
351
|
+
scheme: 'AtomicBoy'
|
352
|
+
)
|
353
|
+
UI.message("Suppressed tests for scheme: #{tests}")
|
354
|
+
|
355
|
+
```
|
356
|
+
|
357
|
+
```ruby
|
358
|
+
|
359
|
+
UI.important(
|
360
|
+
'example: ' \
|
361
|
+
'get the tests that are suppressed in all Schemes in the Project'
|
362
|
+
)
|
363
|
+
UI.message(
|
364
|
+
"Suppressed tests for project: #{suppressed_tests(xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj')}"
|
365
|
+
)
|
366
|
+
|
367
|
+
```
|
368
|
+
<!-- suppressed_tests examples: end -->
|
369
|
+
</details>
|
370
|
+
|
97
371
|
### tests_from_junit
|
98
372
|
|
99
373
|
Performing analysis on a test report file? Get the lists of failing and passing tests using this action.
|
100
374
|
|
375
|
+
<details>
|
376
|
+
<summary>Example Code:</summary>
|
377
|
+
<!-- tests_from_junit examples: begin -->
|
378
|
+
|
379
|
+
```ruby
|
380
|
+
|
381
|
+
UI.important(
|
382
|
+
'example: ' \
|
383
|
+
'get the failed and passing tests from the junit test report file'
|
384
|
+
)
|
385
|
+
result = tests_from_junit(junit: './spec/fixtures/junit.xml')
|
386
|
+
UI.message("Passing tests: #{result[:passing]}")
|
387
|
+
UI.message("Failed tests: #{result[:failed]}")
|
388
|
+
|
389
|
+
```
|
390
|
+
<!-- tests_from_junit examples: end -->
|
391
|
+
</details>
|
392
|
+
|
101
393
|
### tests_from_xctestrun
|
102
394
|
|
103
395
|
Do you have multiple test targets referenced by your `xctestrun` file and need to know all the tests? Use this action to go through each test target, collect the tests, and return them to you in a simple and usable structure.
|
104
396
|
|
397
|
+
<details>
|
398
|
+
<summary>Example Code:</summary>
|
399
|
+
<!-- tests_from_xctestrun examples: begin -->
|
400
|
+
|
401
|
+
```ruby
|
402
|
+
|
403
|
+
require 'fastlane/actions/scan'
|
404
|
+
|
405
|
+
UI.important(
|
406
|
+
'example: ' \
|
407
|
+
'get list of tests that are referenced from an xctestrun file'
|
408
|
+
)
|
409
|
+
# build the tests so that we have a xctestrun file to parse
|
410
|
+
scan(
|
411
|
+
build_for_testing: true,
|
412
|
+
workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
|
413
|
+
scheme: 'AtomicBoy'
|
414
|
+
)
|
415
|
+
|
416
|
+
# find the xctestrun file
|
417
|
+
derived_data_path = Scan.config[:derived_data_path]
|
418
|
+
xctestrun_file = Dir.glob("#{derived_data_path}/Build/Products/*.xctestrun").first
|
419
|
+
|
420
|
+
# get the tests from the xctestrun file
|
421
|
+
tests = tests_from_xctestrun(xctestrun: xctestrun_file)
|
422
|
+
UI.header('xctestrun file contains the following tests')
|
423
|
+
tests.values.flatten.each { |test_identifier| puts test_identifier }
|
424
|
+
|
425
|
+
```
|
426
|
+
<!-- tests_from_xctestrun examples: end -->
|
427
|
+
</details>
|
428
|
+
|
105
429
|
### collate_junit_reports
|
106
430
|
|
107
431
|
Do you have multiple junit test reports coming in from different sources and need it combined? Use this action to collate all the tests performed for a given test target into one report file.
|
108
432
|
|
433
|
+
<details>
|
434
|
+
<summary>Example Code:</summary>
|
435
|
+
<!-- collate_junit_reports examples: begin -->
|
436
|
+
|
437
|
+
```ruby
|
438
|
+
|
439
|
+
UI.important(
|
440
|
+
'example: ' \
|
441
|
+
'collate the xml reports to a temporary file 'result.xml''
|
442
|
+
)
|
443
|
+
collate_junit_reports(
|
444
|
+
reports: Dir['./spec/fixtures/*.xml'],
|
445
|
+
collated_report: File.join(Dir.mktmpdir, 'result.xml')
|
446
|
+
)
|
447
|
+
|
448
|
+
```
|
449
|
+
<!-- collate_junit_reports examples: end -->
|
450
|
+
</details>
|
451
|
+
|
109
452
|
### collate_html_reports
|
110
453
|
|
111
454
|
Do you have multiple html test reports coming in from different sources and need it combined? Use this action to collate all the tests performed for a given test target into one report file.
|
112
455
|
|
113
|
-
|
456
|
+
<details>
|
457
|
+
<summary>Example Code:</summary>
|
458
|
+
<!-- collate_html_reports examples: begin -->
|
459
|
+
|
460
|
+
```ruby
|
114
461
|
|
115
|
-
|
462
|
+
UI.important(
|
463
|
+
'example: ' \
|
464
|
+
'collate the html reports to a temporary file 'result.html''
|
465
|
+
)
|
466
|
+
collate_html_reports(
|
467
|
+
reports: Dir['./spec/fixtures/*.html'],
|
468
|
+
collated_report: File.join(Dir.mktmpdir, 'result.html')
|
469
|
+
)
|
470
|
+
|
471
|
+
```
|
472
|
+
<!-- collate_html_reports examples: end -->
|
473
|
+
</details>
|
116
474
|
|
117
475
|
## Run tests for this plugin
|
118
476
|
|
@@ -163,6 +163,21 @@ module Fastlane
|
|
163
163
|
]
|
164
164
|
end
|
165
165
|
|
166
|
+
def self.example_code
|
167
|
+
[
|
168
|
+
"
|
169
|
+
UI.important(
|
170
|
+
'example: ' \\
|
171
|
+
'collate the html reports to a temporary file \'result.html\''
|
172
|
+
)
|
173
|
+
collate_html_reports(
|
174
|
+
reports: Dir['./spec/fixtures/*.html'],
|
175
|
+
collated_report: File.join(Dir.mktmpdir, 'result.html')
|
176
|
+
)
|
177
|
+
"
|
178
|
+
]
|
179
|
+
end
|
180
|
+
|
166
181
|
def self.authors
|
167
182
|
["lyndsey-ferguson/@lyndseydf"]
|
168
183
|
end
|
@@ -123,6 +123,21 @@ module Fastlane
|
|
123
123
|
]
|
124
124
|
end
|
125
125
|
|
126
|
+
def self.example_code
|
127
|
+
[
|
128
|
+
"
|
129
|
+
UI.important(
|
130
|
+
'example: ' \\
|
131
|
+
'collate the xml reports to a temporary file \'result.xml\''
|
132
|
+
)
|
133
|
+
collate_junit_reports(
|
134
|
+
reports: Dir['./spec/fixtures/*.xml'],
|
135
|
+
collated_report: File.join(Dir.mktmpdir, 'result.xml')
|
136
|
+
)
|
137
|
+
"
|
138
|
+
]
|
139
|
+
end
|
140
|
+
|
126
141
|
def self.authors
|
127
142
|
["lyndsey-ferguson/@lyndseydf"]
|
128
143
|
end
|
@@ -156,38 +156,138 @@ module Fastlane
|
|
156
156
|
|
157
157
|
def self.example_code
|
158
158
|
[
|
159
|
-
|
160
|
-
|
161
|
-
|
159
|
+
"
|
160
|
+
UI.important(
|
161
|
+
'example: ' \\
|
162
|
+
'run tests for a scheme that has two test targets, re-trying up to 2 times if ' \\
|
163
|
+
'tests fail. Turn off the default behavior of failing the build if, at the ' \\
|
164
|
+
'end of the action, there were 1 or more failing tests.'
|
165
|
+
)
|
166
|
+
summary = multi_scan(
|
167
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
168
|
+
scheme: 'AtomicBoy',
|
162
169
|
try_count: 3,
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
170
|
+
fail_build: false,
|
171
|
+
output_files: 'report.html',
|
172
|
+
output_types: 'html'
|
173
|
+
)
|
174
|
+
UI.success(\"multi_scan passed? \#{summary[:result]}\")
|
175
|
+
",
|
176
|
+
"
|
177
|
+
UI.important(
|
178
|
+
'example: ' \\
|
179
|
+
'run tests for a scheme that has two test targets, re-trying up to 2 times if ' \\
|
180
|
+
'tests fail. Make sure that the default behavior of failing the build works.'
|
181
|
+
)
|
182
|
+
begin
|
183
|
+
multi_scan(
|
184
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
185
|
+
scheme: 'AtomicBoy',
|
186
|
+
try_count: 2
|
187
|
+
)
|
188
|
+
rescue FastlaneCore::Interface::FastlaneTestFailure => e
|
189
|
+
UI.success(\"failed successfully with \#{e.message}\")
|
190
|
+
else
|
191
|
+
raise 'This should have failed'
|
192
|
+
end
|
193
|
+
",
|
194
|
+
"
|
195
|
+
UI.important(
|
196
|
+
'example: ' \\
|
197
|
+
'split the tests into 2 batches and run each batch of tests up to 3 ' \\
|
198
|
+
'times if tests fail. Do not fail the build.'
|
199
|
+
)
|
200
|
+
multi_scan(
|
201
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
202
|
+
scheme: 'AtomicBoy',
|
169
203
|
try_count: 3,
|
170
|
-
batch_count: 2,
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
204
|
+
batch_count: 2,
|
205
|
+
fail_build: false
|
206
|
+
)
|
207
|
+
",
|
208
|
+
"
|
209
|
+
UI.important(
|
210
|
+
'example: ' \\
|
211
|
+
'split the tests into 2 batches and run each batch of tests up to 3 ' \\
|
212
|
+
'times if tests fail. Abort the testing early if there are too many ' \\
|
213
|
+
'failing tests by passing in a :testrun_completed_block that is called ' \\
|
214
|
+
'by :multi_scan after each run of tests.'
|
215
|
+
)
|
216
|
+
test_run_block = lambda do |testrun_info|
|
217
|
+
failed_test_count = testrun_info[:failed].size
|
218
|
+
passed_test_count = testrun_info[:passing].size
|
219
|
+
try_attempt = testrun_info[:try_count]
|
220
|
+
batch = testrun_info[:batch]
|
221
|
+
|
222
|
+
if passed_test_count > 0 && failed_test_count > passed_test_count / 2
|
223
|
+
UI.abort_with_message!(\"Too many tests are failing\")
|
224
|
+
end
|
225
|
+
UI.message(\"\\\u1F60A everything is fine, let's continue try \#{try_attempt + 1} for batch \#{batch}\")
|
226
|
+
end
|
227
|
+
|
228
|
+
multi_scan(
|
229
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
230
|
+
scheme: 'AtomicBoy',
|
177
231
|
try_count: 3,
|
178
|
-
batch_count:
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
232
|
+
batch_count: 2,
|
233
|
+
fail_build: false,
|
234
|
+
testrun_completed_block: test_run_block
|
235
|
+
)
|
236
|
+
",
|
237
|
+
"
|
238
|
+
UI.important(
|
239
|
+
'example: ' \\
|
240
|
+
'use the :workspace parameter instead of the :project parameter to find, ' \\
|
241
|
+
'build, and test the iOS app.'
|
242
|
+
)
|
243
|
+
multi_scan(
|
244
|
+
workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
|
245
|
+
scheme: 'AtomicBoy',
|
246
|
+
try_count: 3
|
247
|
+
)
|
248
|
+
",
|
249
|
+
"
|
250
|
+
UI.important(
|
251
|
+
'example: ' \\
|
252
|
+
'use the :workspace parameter instead of the :project parameter to find, ' \\
|
253
|
+
'build, and test the iOS app. Use the :skip_build parameter to not rebuild.'
|
254
|
+
)
|
255
|
+
multi_scan(
|
256
|
+
workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
|
257
|
+
scheme: 'AtomicBoy',
|
258
|
+
skip_build: true,
|
259
|
+
clean: true,
|
260
|
+
try_count: 3,
|
261
|
+
result_bundle: true
|
262
|
+
)
|
263
|
+
",
|
264
|
+
"
|
265
|
+
UI.important(
|
266
|
+
'example: ' \\
|
267
|
+
'multi_scan also works with just one test target in the Scheme.'
|
268
|
+
)
|
269
|
+
multi_scan(
|
270
|
+
project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
|
271
|
+
scheme: 'Professor',
|
272
|
+
try_count: 3,
|
273
|
+
custom_report_file_name: 'atomic_report.xml',
|
274
|
+
output_types: 'junit,html',
|
275
|
+
fail_build: false
|
276
|
+
)
|
277
|
+
",
|
278
|
+
"
|
279
|
+
UI.important(
|
280
|
+
'example: ' \\
|
281
|
+
'multi_scan also can also run just the tests passed in the ' \\
|
282
|
+
':only_testing option.'
|
283
|
+
)
|
284
|
+
multi_scan(
|
285
|
+
workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
|
286
|
+
scheme: 'AtomicBoy',
|
287
|
+
try_count: 3,
|
288
|
+
only_testing: ['AtomicBoyTests']
|
289
|
+
)
|
290
|
+
"
|
191
291
|
]
|
192
292
|
end
|
193
293
|
|
@@ -81,6 +81,38 @@ module Fastlane
|
|
81
81
|
]
|
82
82
|
end
|
83
83
|
|
84
|
+
def self.example_code
|
85
|
+
[
|
86
|
+
"
|
87
|
+
UI.important(
|
88
|
+
'example: ' \\
|
89
|
+
'suppress some tests in all Schemes for a Project'
|
90
|
+
)
|
91
|
+
suppress_tests(
|
92
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
93
|
+
tests: [
|
94
|
+
'AtomicBoyUITests/HappyNapperTests/testBeepingNonExistentFriendDisplaysError',
|
95
|
+
'AtomicBoyUITests/GrumpyWorkerTests'
|
96
|
+
]
|
97
|
+
)
|
98
|
+
",
|
99
|
+
"
|
100
|
+
UI.important(
|
101
|
+
'example: ' \\
|
102
|
+
'suppress some tests in one Scheme for a Project'
|
103
|
+
)
|
104
|
+
suppress_tests(
|
105
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
106
|
+
tests: [
|
107
|
+
'AtomicBoyUITests/HappyNapperTests/testBeepingNonExistentFriendDisplaysError',
|
108
|
+
'AtomicBoyUITests/GrumpyWorkerTests'
|
109
|
+
],
|
110
|
+
scheme: 'Professor'
|
111
|
+
)
|
112
|
+
"
|
113
|
+
]
|
114
|
+
end
|
115
|
+
|
84
116
|
def self.authors
|
85
117
|
["lyndsey-ferguson/@lyndseydf"]
|
86
118
|
end
|
@@ -90,6 +90,40 @@ module Fastlane
|
|
90
90
|
]
|
91
91
|
end
|
92
92
|
|
93
|
+
def self.example_code
|
94
|
+
[
|
95
|
+
"
|
96
|
+
UI.important(
|
97
|
+
'example: ' \\
|
98
|
+
'suppress the tests that failed in the junit report for _all_ Schemes'
|
99
|
+
)
|
100
|
+
suppress_tests_from_junit(
|
101
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
102
|
+
junit: './spec/fixtures/junit.xml',
|
103
|
+
suppress_type: :failed
|
104
|
+
)
|
105
|
+
UI.message(
|
106
|
+
\"Suppressed tests for project: \#{suppressed_tests(xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj')}\"
|
107
|
+
)
|
108
|
+
",
|
109
|
+
"
|
110
|
+
UI.important(
|
111
|
+
'example: ' \\
|
112
|
+
'suppress the tests that failed in the junit report for _one_ Scheme'
|
113
|
+
)
|
114
|
+
suppress_tests_from_junit(
|
115
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
116
|
+
junit: './spec/fixtures/junit.xml',
|
117
|
+
scheme: 'Professor',
|
118
|
+
suppress_type: :failed
|
119
|
+
)
|
120
|
+
UI.message(
|
121
|
+
\"Suppressed tests for the 'Professor' scheme: \#{suppressed_tests(xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj')}\"
|
122
|
+
)
|
123
|
+
"
|
124
|
+
]
|
125
|
+
end
|
126
|
+
|
93
127
|
def self.authors
|
94
128
|
["lyndsey-ferguson/@lyndseydf"]
|
95
129
|
end
|
@@ -60,6 +60,31 @@ module Fastlane
|
|
60
60
|
]
|
61
61
|
end
|
62
62
|
|
63
|
+
def self.example_code
|
64
|
+
[
|
65
|
+
"
|
66
|
+
UI.important(
|
67
|
+
'example: ' \\
|
68
|
+
'get the tests that are suppressed in a Scheme in the Project'
|
69
|
+
)
|
70
|
+
tests = suppressed_tests(
|
71
|
+
xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
|
72
|
+
scheme: 'AtomicBoy'
|
73
|
+
)
|
74
|
+
UI.message(\"Suppressed tests for scheme: \#{tests}\")
|
75
|
+
",
|
76
|
+
"
|
77
|
+
UI.important(
|
78
|
+
'example: ' \\
|
79
|
+
'get the tests that are suppressed in all Schemes in the Project'
|
80
|
+
)
|
81
|
+
UI.message(
|
82
|
+
\"Suppressed tests for project: \#{suppressed_tests(xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj')}\"
|
83
|
+
)
|
84
|
+
"
|
85
|
+
]
|
86
|
+
end
|
87
|
+
|
63
88
|
def self.authors
|
64
89
|
["lyndsey-ferguson/@lyndseydf"]
|
65
90
|
end
|
@@ -57,6 +57,20 @@ module Fastlane
|
|
57
57
|
"a Hash with :message and :location details for the failed test"
|
58
58
|
end
|
59
59
|
|
60
|
+
def self.example_code
|
61
|
+
[
|
62
|
+
"
|
63
|
+
UI.important(
|
64
|
+
'example: ' \\
|
65
|
+
'get the failed and passing tests from the junit test report file'
|
66
|
+
)
|
67
|
+
result = tests_from_junit(junit: './spec/fixtures/junit.xml')
|
68
|
+
UI.message(\"Passing tests: \#{result[:passing]}\")
|
69
|
+
UI.message(\"Failed tests: \#{result[:failed]}\")
|
70
|
+
"
|
71
|
+
]
|
72
|
+
end
|
73
|
+
|
60
74
|
def self.authors
|
61
75
|
["lyndsey-ferguson/lyndseydf"]
|
62
76
|
end
|
@@ -53,6 +53,34 @@ module Fastlane
|
|
53
53
|
"A Hash of testable => tests, where testable is the name of the test target and tests is an array of test identifiers"
|
54
54
|
end
|
55
55
|
|
56
|
+
def self.example_code
|
57
|
+
[
|
58
|
+
"
|
59
|
+
require 'fastlane/actions/scan'
|
60
|
+
|
61
|
+
UI.important(
|
62
|
+
'example: ' \\
|
63
|
+
'get list of tests that are referenced from an xctestrun file'
|
64
|
+
)
|
65
|
+
# build the tests so that we have a xctestrun file to parse
|
66
|
+
scan(
|
67
|
+
build_for_testing: true,
|
68
|
+
workspace: File.absolute_path('../AtomicBoy/AtomicBoy.xcworkspace'),
|
69
|
+
scheme: 'AtomicBoy'
|
70
|
+
)
|
71
|
+
|
72
|
+
# find the xctestrun file
|
73
|
+
derived_data_path = Scan.config[:derived_data_path]
|
74
|
+
xctestrun_file = Dir.glob(\"\#{derived_data_path}/Build/Products/*.xctestrun\").first
|
75
|
+
|
76
|
+
# get the tests from the xctestrun file
|
77
|
+
tests = tests_from_xctestrun(xctestrun: xctestrun_file)
|
78
|
+
UI.header('xctestrun file contains the following tests')
|
79
|
+
tests.values.flatten.each { |test_identifier| puts test_identifier }
|
80
|
+
"
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
56
84
|
def self.authors
|
57
85
|
["lyndsey-ferguson/lyndseydf"]
|
58
86
|
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.2.
|
4
|
+
version: 3.2.3
|
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-
|
11
|
+
date: 2018-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: plist
|