fastlane-plugin-test_center 3.4.0 → 3.5.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: '083be0187ece34a8f7019e4992c1fa2330b4732d'
4
- data.tar.gz: 364b206944566949934477d518853537f27cdabb
3
+ metadata.gz: 2c6a17f7ee4ae4381b5cff509b6ea0d2a7e860b8
4
+ data.tar.gz: 79aac0aa87a128f9ab42841a1c5b8b87db1165b8
5
5
  SHA512:
6
- metadata.gz: 64532eb3e5dfe6afdf6b49fe27555e58d052fc60cf3d57363becf437704e0519a696889032f0106fabafabaf5ab808f0f713b059af75a38f0e9aecc44e8f2cde
7
- data.tar.gz: 301e3e7946ab86b32aa310fd73b01cb2b222c00b99d1a255575964c1bed55ca864bf66b55ff2d50690776ff399d3c57335ac3d6737de2262c50a720a565af0e5
6
+ metadata.gz: 602af20f6d4659244c748df0907077e87b432756d1f3c8cf55873f29b8c47432d5f62a4ad6e07227a54313a959e97b2662a3cb6308c35ecc1f38f0764d7eea62
7
+ data.tar.gz: '096cb269e5fad71c010807212a466dc6067fa6dc86f63c9ba1484c6200d71d8af5a2bdf3965f6dd95c6155119b6d069bbd5294d6f067d781faa65e4bc5c170c9'
data/README.md CHANGED
@@ -70,6 +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
  - [`collate_json_reports`](#collate_json_reports): combines multiple json test reports into one report.
73
+ - [`collate_test_result_bundles`](#collate_test_result_bundles): combines multiple test_result bundles into one test_result bundle.
73
74
 
74
75
  ### multi_scan 🎉
75
76
 
@@ -107,27 +108,6 @@ UI.success("multi_scan passed? #{summary[:result]}")
107
108
 
108
109
  ```ruby
109
110
 
110
- UI.important(
111
- 'example: ' \
112
- 'run tests for a scheme that has two test targets, re-trying up to 2 times if ' \
113
- 'tests fail. Make sure that the default behavior of failing the build works.'
114
- )
115
- begin
116
- multi_scan(
117
- project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
118
- scheme: 'AtomicBoy',
119
- try_count: 2
120
- )
121
- rescue FastlaneCore::Interface::FastlaneTestFailure => e
122
- UI.success("failed successfully with #{e.message}")
123
- else
124
- raise 'This should have failed'
125
- end
126
-
127
- ```
128
-
129
- ```ruby
130
-
131
111
  UI.important(
132
112
  'example: ' \
133
113
  'split the tests into 2 batches and run each batch of tests up to 3 ' \
@@ -158,9 +138,7 @@ test_run_block = lambda do |testrun_info|
158
138
  try_attempt = testrun_info[:try_count]
159
139
  batch = testrun_info[:batch]
160
140
 
161
- if passed_test_count > 0 && failed_test_count > passed_test_count / 2
162
- UI.abort_with_message!("Too many tests are failing")
163
- end
141
+ # UI.abort_with_message!('You could conditionally abort')
164
142
  UI.message("\ὠA everything is fine, let's continue try #{try_attempt + 1} for batch #{batch}")
165
143
  end
166
144
 
@@ -220,7 +198,7 @@ multi_scan(
220
198
  scheme: 'Professor',
221
199
  try_count: 3,
222
200
  custom_report_file_name: 'atomic_report.xml',
223
- output_types: 'junit,html',
201
+ output_types: 'junit',
224
202
  fail_build: false
225
203
  )
226
204
 
@@ -549,6 +527,30 @@ collate_json_reports(
549
527
  <!-- collate_json_reports examples: end -->
550
528
  </details>
551
529
 
530
+ ### collate_test_result_bundles
531
+
532
+ Do you have multiple test_result bundles 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 test_result bundle.
533
+
534
+ <details>
535
+ <summary>Example Code:</summary>
536
+ <!-- collate_test_result_bundles examples: begin -->
537
+
538
+ ```ruby
539
+
540
+ UI.important(
541
+ 'example: ' \
542
+ 'collate the test_result bundles to a temporary bundle "result.test_result"'
543
+ )
544
+ bundles = Dir['../spec/fixtures/*.test_result'].map { |relpath| File.absolute_path(relpath) }
545
+ collate_test_result_bundles(
546
+ bundles: bundles,
547
+ collated_bundle: File.join(Dir.mktmpdir, 'result.test_result')
548
+ )
549
+
550
+ ```
551
+ <!-- collate_test_result_bundles examples: end -->
552
+ </details>
553
+
552
554
  ## Run tests for this plugin
553
555
 
554
556
  To run both the tests, and code style validation, run
@@ -0,0 +1,180 @@
1
+ module Fastlane
2
+ module Actions
3
+ class CollateTestResultBundlesAction < Action
4
+ require 'plist'
5
+
6
+ def self.run(params)
7
+ test_result_bundlepaths = params[:bundles]
8
+ base_bundle_path = test_result_bundlepaths[0]
9
+ if test_result_bundlepaths.size > 1
10
+ base_bundle_path = Dir.mktmpdir(['base', '.test_result'])
11
+ FileUtils.cp_r(File.join(test_result_bundlepaths[0], '.'), base_bundle_path)
12
+ test_result_bundlepaths.shift
13
+ test_result_bundlepaths.each do |other_bundlepath|
14
+ collate_bundles(base_bundle_path, other_bundlepath)
15
+ end
16
+ end
17
+ FileUtils.rm_rf(params[:collated_bundle])
18
+ FileUtils.cp_r(base_bundle_path, params[:collated_bundle])
19
+ UI.message("Finished collating test_result bundle to '#{params[:collated_bundle]}'")
20
+ end
21
+
22
+ def self.collate_bundles(base_bundle_path, other_bundle_path)
23
+ Dir.foreach(other_bundle_path) do |child_item|
24
+ if child_item == 'Info.plist'
25
+ collate_infoplist(
26
+ File.join(base_bundle_path, child_item),
27
+ File.join(other_bundle_path, child_item)
28
+ )
29
+ elsif /\d_Test/ =~ child_item
30
+ test_target_path = File.join(base_bundle_path, child_item)
31
+ other_target_path = File.join(other_bundle_path, child_item)
32
+ Dir.foreach(other_target_path) do |grandchild_item|
33
+ collate_bundle(test_target_path, other_target_path, grandchild_item)
34
+ end
35
+ else
36
+ collate_bundle(base_bundle_path, other_bundle_path, child_item)
37
+ end
38
+ end
39
+ end
40
+
41
+ def self.collate_bundle(base_bundle_path, other_bundle_path, child_item_name)
42
+ if %w{Attachments Diagnostics}.include?(child_item_name)
43
+ FileUtils.cp_r(
44
+ File.join(other_bundle_path, child_item_name, '.'),
45
+ File.join(base_bundle_path, child_item_name)
46
+ )
47
+ elsif child_item_name.end_with?('.xcactivitylog')
48
+ concatenate_zipped_activitylogs(
49
+ File.join(base_bundle_path, child_item_name),
50
+ File.join(other_bundle_path, child_item_name)
51
+ )
52
+ elsif child_item_name.end_with?('TestSummaries.plist')
53
+ collate_testsummaries_plist(
54
+ File.join(base_bundle_path, child_item_name),
55
+ File.join(other_bundle_path, child_item_name)
56
+ )
57
+ end
58
+ end
59
+
60
+ def self.concatenate_zipped_activitylogs(base_activity_log_path, other_activity_log_path)
61
+ gunzipped_base_filepath = File.join(
62
+ File.dirname(base_activity_log_path),
63
+ File.basename(base_activity_log_path, '.*')
64
+ )
65
+ gunzipped_other_filepath = File.join(
66
+ File.dirname(other_activity_log_path),
67
+ File.basename(other_activity_log_path, '.*')
68
+ )
69
+ sh("gunzip -k -S .xcactivitylog #{other_activity_log_path}", print_command: false, print_command_output: false)
70
+ sh("gunzip -S .xcactivitylog #{base_activity_log_path}", print_command: false, print_command_output: false)
71
+ sh("cat #{gunzipped_other_filepath} > #{gunzipped_base_filepath}", print_command: false, print_command_output: false)
72
+ FileUtils.rm(gunzipped_other_filepath)
73
+ sh("gzip -S .xcactivitylog #{gunzipped_base_filepath}", print_command: false, print_command_output: false)
74
+ end
75
+
76
+ def self.collate_testsummaries_plist(base_testsummaries_plist_filepath, other_testsummaries_plist_filepath)
77
+ if File.exist?(base_testsummaries_plist_filepath)
78
+ base_testsummaries_plist = Plist.parse_xml(base_testsummaries_plist_filepath)
79
+ other_testsummaries_plist = Plist.parse_xml(other_testsummaries_plist_filepath)
80
+ base_testsummaries_plist['TestableSummaries'].zip(other_testsummaries_plist['TestableSummaries']).each do |base_testable_summary, other_testable_summary|
81
+ unless base_testable_summary.key?('PreviousTests')
82
+ base_testable_summary['PreviousTests'] = []
83
+ end
84
+ base_testable_summary['PreviousTests'].concat(base_testable_summary['Tests'] || [])
85
+ base_testable_summary['Tests'] = other_testable_summary['Tests']
86
+ end
87
+ Plist::Emit.save_plist(base_testsummaries_plist, base_testsummaries_plist_filepath)
88
+ else
89
+ FileUtils.cp(other_testsummaries_plist, base_testsummaries_plist)
90
+ end
91
+ end
92
+
93
+ def self.collate_infoplist(base_infoplist_filepath, other_infoplist_filepath)
94
+ if File.exist?(base_infoplist_filepath)
95
+ base_infoplist = Plist.parse_xml(base_infoplist_filepath)
96
+ other_infoplist = Plist.parse_xml(other_infoplist_filepath)
97
+ other_infoplist['Actions'].zip(base_infoplist['Actions']).each do |other_action, base_action|
98
+ if other_action['Title'] != base_action['Title']
99
+ raise 'Info.plist Actions do not align: cannot collate'
100
+ end
101
+ base_action['EndedTime'] = other_action['EndedTime']
102
+ base_action['ActionResult']['TestsFailedCount'] = other_action['ActionResult']['TestsFailedCount']
103
+ end
104
+ Plist::Emit.save_plist(base_infoplist, base_infoplist_filepath)
105
+ else
106
+ FileUtils.cp(other_infoplist_filepath, base_infoplist_filepath)
107
+ end
108
+ end
109
+
110
+ #####################################################
111
+ # @!group Documentation
112
+ #####################################################
113
+
114
+ def self.description
115
+ "Combines and combines tests from multiple test_result bundles"
116
+ end
117
+
118
+ def self.details
119
+ "The first test_result bundle is used as the base bundle. " \
120
+ "Testcases that failed in previous bundles that no longer appear in " \
121
+ "later bundles are assumed to have passed in a re-run, thus not appearing " \
122
+ "in the collated test_result bundle. " \
123
+ "This is done because it is assumed that fragile tests, when " \
124
+ "re-run will often succeed due to less interference from other " \
125
+ "tests and the subsequent test_result bundles will have fewer failing tests." \
126
+ ""
127
+ end
128
+
129
+ def self.available_options
130
+ [
131
+ FastlaneCore::ConfigItem.new(
132
+ key: :bundles,
133
+ env_name: 'COLLATE_TEST_RESULT_BUNDLES_BUNDLES',
134
+ description: 'An array of test_result bundles to collate. The first bundle is used as the base into which other bundles are merged in',
135
+ optional: false,
136
+ type: Array,
137
+ verify_block: proc do |bundles|
138
+ UI.user_error!('No test_result bundles found') if bundles.empty?
139
+ bundles.each do |bundle|
140
+ UI.user_error!("Error: test_result bundle not found: '#{bundle}'") unless Dir.exist?(bundle)
141
+ end
142
+ end
143
+ ),
144
+ FastlaneCore::ConfigItem.new(
145
+ key: :collated_bundle,
146
+ env_name: 'COLLATE_TEST_RESULT_BUNDLES_COLLATED_BUNDLE',
147
+ description: 'The final test_result bundle where all testcases will be merged into',
148
+ optional: true,
149
+ default_value: 'result.test_result',
150
+ type: String
151
+ )
152
+ ]
153
+ end
154
+
155
+ def self.example_code
156
+ [
157
+ "
158
+ UI.important(
159
+ 'example: ' \\
160
+ 'collate the test_result bundles to a temporary bundle \"result.test_result\"'
161
+ )
162
+ bundles = Dir['../spec/fixtures/*.test_result'].map { |relpath| File.absolute_path(relpath) }
163
+ collate_test_result_bundles(
164
+ bundles: bundles,
165
+ collated_bundle: File.join(Dir.mktmpdir, 'result.test_result')
166
+ )
167
+ "
168
+ ]
169
+ end
170
+
171
+ def self.authors
172
+ ["lyndsey-ferguson/@lyndseydf"]
173
+ end
174
+
175
+ def self.is_supported?(platform)
176
+ platform == :ios
177
+ end
178
+ end
179
+ end
180
+ end
@@ -63,6 +63,11 @@ module Fastlane
63
63
  File.absolute_path(relative_filepath)
64
64
  end
65
65
  end
66
+ if scan_options[:result_bundle]
67
+ report_files += Dir.glob("#{scan_options[:output_directory]}/**/*.test_result").map do |relative_test_result_bundle_filepath|
68
+ File.absolute_path(relative_test_result_bundle_filepath)
69
+ end
70
+ end
66
71
  {
67
72
  result: tests_passed,
68
73
  total_tests: passing_testcount + failed_tests.size,
@@ -188,24 +193,6 @@ module Fastlane
188
193
  UI.success(\"multi_scan passed? \#{summary[:result]}\")
189
194
  ",
190
195
  "
191
- UI.important(
192
- 'example: ' \\
193
- 'run tests for a scheme that has two test targets, re-trying up to 2 times if ' \\
194
- 'tests fail. Make sure that the default behavior of failing the build works.'
195
- )
196
- begin
197
- multi_scan(
198
- project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
199
- scheme: 'AtomicBoy',
200
- try_count: 2
201
- )
202
- rescue FastlaneCore::Interface::FastlaneTestFailure => e
203
- UI.success(\"failed successfully with \#{e.message}\")
204
- else
205
- raise 'This should have failed'
206
- end
207
- ",
208
- "
209
196
  UI.important(
210
197
  'example: ' \\
211
198
  'split the tests into 2 batches and run each batch of tests up to 3 ' \\
@@ -233,9 +220,7 @@ module Fastlane
233
220
  try_attempt = testrun_info[:try_count]
234
221
  batch = testrun_info[:batch]
235
222
 
236
- if passed_test_count > 0 && failed_test_count > passed_test_count / 2
237
- UI.abort_with_message!(\"Too many tests are failing\")
238
- end
223
+ # UI.abort_with_message!('You could conditionally abort')
239
224
  UI.message(\"\\\u1F60A everything is fine, let's continue try \#{try_attempt + 1} for batch \#{batch}\")
240
225
  end
241
226
 
@@ -286,7 +271,7 @@ module Fastlane
286
271
  scheme: 'Professor',
287
272
  try_count: 3,
288
273
  custom_report_file_name: 'atomic_report.xml',
289
- output_types: 'junit,html',
274
+ output_types: 'junit',
290
275
  fail_build: false
291
276
  )
292
277
  ",
@@ -103,6 +103,10 @@ module TestCenter
103
103
  if reportnamer.includes_json?
104
104
  collate_json_reports(output_directory, reportnamer)
105
105
  end
106
+
107
+ if @scan_options[:result_bundle]
108
+ collate_test_result_bundles(output_directory, reportnamer)
109
+ end
106
110
  end
107
111
 
108
112
  def passed_test_count_from_summary(summary)
@@ -110,6 +114,24 @@ module TestCenter
110
114
  test_count.to_i - test_failures.to_i
111
115
  end
112
116
 
117
+ def collate_test_result_bundles(output_directory, reportnamer)
118
+ test_result_bundlepaths = Dir.glob("#{output_directory}/#{@scan_options[:scheme]}*.test_result").map do |relative_test_result_bundle_filepath|
119
+ File.absolute_path(relative_test_result_bundle_filepath)
120
+ end
121
+ if test_result_bundlepaths.size > 1
122
+ config = FastlaneCore::Configuration.create(
123
+ Fastlane::Actions::CollateTestResultBundlesAction.available_options,
124
+ {
125
+ bundles: test_result_bundlepaths.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
126
+ collated_bundle: File.join(output_directory, @scan_options[:scheme]) + '.test_result'
127
+ }
128
+ )
129
+ Fastlane::Actions::CollateTestResultBundlesAction.run(config)
130
+ end
131
+ retried_test_result_bundlepaths = Dir.glob("#{output_directory}/#{@scan_options[:scheme]}_*.test_result")
132
+ FileUtils.rm_rf(retried_test_result_bundlepaths)
133
+ end
134
+
113
135
  def collate_json_reports(output_directory, reportnamer)
114
136
  report_filepaths = Dir.glob("#{output_directory}/#{reportnamer.json_fileglob}").map do |relative_filepath|
115
137
  File.absolute_path(relative_filepath)
@@ -198,13 +220,13 @@ module TestCenter
198
220
 
199
221
  scan_options[:only_testing] = info[:failed].map(&:shellescape)
200
222
  FastlaneCore::UI.message('Re-running scan on only failed tests')
223
+ reportnamer.increment
201
224
  if @scan_options[:result_bundle]
202
225
  built_test_result, moved_test_result = test_result_bundlepaths(
203
226
  scan_options[:output_directory], reportnamer
204
227
  )
205
228
  FileUtils.mv(built_test_result, moved_test_result)
206
229
  end
207
- reportnamer.increment
208
230
  retry
209
231
  end
210
232
  tests_passed = false
@@ -239,6 +261,12 @@ module TestCenter
239
261
  json_report_filepath = File.join(output_directory, reportnamer.json_last_reportname)
240
262
  info[:json_report_filepath] = json_report_filepath
241
263
  end
264
+ if @scan_options[:result_bundle]
265
+ test_result_suffix = '.test_result'
266
+ test_result_suffix.prepend("_#{reportnamer.report_count}") unless reportnamer.report_count.zero?
267
+ test_result_bundlepath = File.join(output_directory, @scan_options[:scheme]) + test_result_suffix
268
+ info[:test_result_bundlepath] = test_result_bundlepath
269
+ end
242
270
  info
243
271
  end
244
272
 
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TestCenter
3
- VERSION = "3.4.0"
3
+ VERSION = "3.5.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: 3.4.0
4
+ version: 3.5.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-06-24 00:00:00.000000000 Z
11
+ date: 2018-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -206,15 +206,8 @@ dependencies:
206
206
  - - ">="
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
- description: |2
210
- This fastlane plugin includes the following actions:
211
- 1) multi_scan: uses scan to run Xcode tests, optionally in batches, a given number of times: only re-testing failing tests.
212
- 2) suppress_tests_from_junit: uses a junit xml report file to suppress either passing or failing tests in an Xcode Scheme.
213
- 3) suppress_tests: suppresses specific tests in a specific or all Xcode Schemes in a given project.
214
- 4) suppressed_tests: retrieves a list of tests that are suppressed in a specific or all Xcode Schemes in a project.
215
- 5) tests_from_junit: retrieves the failing and passing tests as reported in a junit xml file.
216
- 6) tests_from_xctestrun: retrieves all of the tests from xctest bundles referenced by the xctestrun file
217
- 7) collate_junit_reports: collects and correctly organizes junit reports from multiple test passes.
209
+ description: " This fastlane plugin includes the following many actions to better
210
+ manage how you test, what you test, and the information you get from your tests\n"
218
211
  email: ldf.public+github@outlook.com
219
212
  executables: []
220
213
  extensions: []
@@ -226,6 +219,7 @@ files:
226
219
  - lib/fastlane/plugin/test_center/actions/collate_html_reports.rb
227
220
  - lib/fastlane/plugin/test_center/actions/collate_json_reports.rb
228
221
  - lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb
222
+ - lib/fastlane/plugin/test_center/actions/collate_test_result_bundles.rb
229
223
  - lib/fastlane/plugin/test_center/actions/multi_scan.rb
230
224
  - lib/fastlane/plugin/test_center/actions/suppress_tests.rb
231
225
  - lib/fastlane/plugin/test_center/actions/suppress_tests_from_junit.rb