fastlane-plugin-test_center 3.2.2 → 3.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|